diff options
author | anholt <anholt> | 2003-08-23 00:20:19 +0000 |
---|---|---|
committer | anholt <anholt> | 2003-08-23 00:20:19 +0000 |
commit | 387c76f0b6db4ebbfe195f38798373db0677801d (patch) | |
tree | d1214aaa353fdd43ea34ac2d3fe4add980bd76a7 /xc/programs/Xserver | |
parent | 0879b8ec6fa78fbba50bb426c6e97285256d1603 (diff) |
Bring over sis driver from XFree86 CVS. The added files were missing though
required by the driver before, so it was decided to update the whole thing
while I'm here.
Diffstat (limited to 'xc/programs/Xserver')
38 files changed, 42002 insertions, 11745 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h index a6989da1c..c058895fd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h @@ -1,8 +1,37 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h,v 1.6 2003/02/10 01:14:16 tsi Exp $ */ - - -/* Register settings for SiS 300 series */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h,v 1.14 2003/07/28 12:39:45 twini Exp $ */ +/* + * Register settings for SiS 300 series + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * Based on code by Silicon Intergrated Systems + * + */ typedef struct _SiS300_StStruct { @@ -40,470 +69,109 @@ static const SiS300_StStruct SiS300_SModeIDTable[] = {0xff, 0, 0, 0, 0, 0, 0, 0} }; -typedef struct _SiS300_StandTableStruct -{ - UCHAR CRT_COLS; - UCHAR ROWS; - UCHAR CHAR_HEIGHT; - USHORT CRT_LEN; - UCHAR SR[4]; - UCHAR MISC; - UCHAR CRTC[0x19]; - UCHAR ATTR[0x14]; - UCHAR GRC[9]; -} SiS300_StandTableStruct; - -static const SiS300_StandTableStruct SiS300_StandTable[] = -{ - {0x28,0x18,0x08,0x0800, /* 0x00 */ - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x28,0x18,0x08,0x0800, /* 0x01 */ - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x50,0x18,0x08,0x1000, /* 0x02 */ - {0x01,0x03,0x00,0x02}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x50,0x18,0x08,0x1000, /* 0x03 */ - {0x01,0x03,0x00,0x02}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x28,0x18,0x08,0x4000, /* 0x04 */ - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f, - 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, - 0xff}, - {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x03,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, - 0xff} }, - {0x28,0x18,0x08,0x4000, /* 0x05 */ - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f, - 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, - 0xff}, - {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x03,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, - 0xff} }, - {0x50,0x18,0x08,0x4000, /* 0x06 */ - {0x01,0x01,0x00,0x06}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, - 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2, - 0xff}, - {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17, - 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, - 0x01,0x00,0x01,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00, - 0xff} }, - {0x50,0x18,0x0e,0x1000, /* 0x07 */ - {0x00,0x03,0x00,0x03}, - 0xa6, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3, - 0xff}, - {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, - 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, - 0x0e,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, - 0xff} }, -/* MDA_DAC*/ - {0x00,0x00,0x00,0x0000, /* 0x08 */ - {0x00,0x00,0x00,0x15}, - 0x15, - {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, - 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f, - 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00, - 0x00}, - {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15, - 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, - 0x15,0x15,0x15,0x15}, - {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, - 0x3f} }, -/* CGA_DAC*/ - {0x00,0x10,0x04,0x0114, /* 0x09 */ - {0x11,0x09,0x15,0x00}, - 0x10, - {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a, - 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a, - 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10, - 0x04}, - {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04, - 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e, - 0x3e,0x2b,0x3b,0x2f}, - {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, - 0x3f} }, -/* EGA_DAC*/ - {0x00,0x10,0x04,0x0114, /* 0x0a */ - {0x11,0x05,0x15,0x20}, - 0x30, - {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18, - 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38, - 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12, - 0x06}, - {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26, - 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e, - 0x1e,0x0b,0x1b,0x0f}, - {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, - 0x3f} }, -/* VGA_DAC*/ - {0x00,0x10,0x04,0x0114, /* 0x0b */ - {0x11,0x09,0x15,0x2a}, - 0x3a, - {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05, - 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20, - 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10, - 0x1f}, - {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d, - 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15, - 0x1c,0x0e,0x11,0x15}, - {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00, - 0x04} }, - {0x08,0x0c,0x10,0x0a08, /* 0x0c */ - {0x0c,0x0e,0x10,0x0b}, - 0x0c, - {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00, - 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00, - 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00, - 0x06}, - {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08, - 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00, - 0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00} }, - {0x28,0x18,0x08,0x2000, /* 0x0d */ - {0x09,0x0f,0x00,0x06}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f, - 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} }, - {0x50,0x18,0x08,0x4000, /* 0x0e */ - {0x01,0x0f,0x00,0x06}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, - 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} }, - {0x00,0x00,0x00,0x0000, /* 0x0f */ /* TW: Standtable for VGA modes */ - {0x01,0x0f,0x00,0x0e}, - 0x23, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x01,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, - 0xff} }, - {0x4a,0x36,0x00,0x00c0, /* 0x10 */ - {0x00,0x00,0x00,0x00}, - 0x00, - {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a, - 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0, - 0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00} }, - {0x50,0x18,0x0e,0x8000, /* 0x11 */ - {0x01,0x0f,0x00,0x06}, - 0xa2, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3, - 0xff}, - {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00, - 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00, - 0x0b,0x00,0x05,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05, - 0xff} }, - {0x50,0x18,0x0e,0x8000, /* 0x12 */ - {0x01,0x0f,0x00,0x06}, - 0xa3, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} }, - {0x28,0x18,0x0e,0x0800, /* 0x13 */ - {0x09,0x03,0x00,0x02}, - 0xa3, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x28,0x18,0x0e,0x0800, /* 0x14 */ - {0x09,0x03,0x00,0x02}, - 0xa3, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x50,0x18,0x0e,0x1000, /* 0x15 */ - {0x01,0x03,0x00,0x02}, - 0xa3, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x50,0x18,0x0e,0x1000, /* 0x16 */ - {0x01,0x03,0x00,0x02}, - 0xa3, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x28,0x18,0x10,0x0800, /* 0x17 */ - {0x08,0x03,0x00,0x02}, - 0x67, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x0c,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x50,0x18,0x10,0x1000, /* 0x18 */ - {0x00,0x03,0x00,0x02}, - 0x67, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x0c,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} }, - {0x50,0x18,0x10,0x1000, /* 0x19 */ - {0x00,0x03,0x00,0x02}, - 0x66, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, - 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, - 0x0e,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, - 0xff} }, - {0x50,0x1d,0x10,0xa000, /* 0x1a */ - {0x01,0x0f,0x00,0x06}, - 0xe3, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3, - 0xff}, - {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, - 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01, - 0xff} }, - {0x50,0x1d,0x10,0xa000, /* 0x1b */ - {0x01,0x0f,0x00,0x06}, - 0xe3, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} }, - {0x28,0x18,0x08,0x2000, /* 0x1c */ - {0x01,0x0f,0x00,0x0e}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, - 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x41,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, - 0xff} } -}; - typedef struct _SiS300_ExtStruct { - UCHAR Ext_ModeID; + UCHAR Ext_ModeID; USHORT Ext_ModeFlag; USHORT Ext_ModeInfo; - USHORT Ext_Point; USHORT Ext_VESAID; - UCHAR Ext_VESAMEMSize; - UCHAR Ext_RESINFO; - UCHAR VB_ExtTVFlickerIndex; - UCHAR VB_ExtTVEdgeIndex; - UCHAR VB_ExtTVYFilterIndex; - UCHAR REFindex; + UCHAR Ext_RESINFO; + UCHAR VB_ExtTVFlickerIndex; + UCHAR VB_ExtTVEdgeIndex; + UCHAR VB_ExtTVYFilterIndex; + UCHAR REFindex; } SiS300_ExtStruct; static const SiS300_ExtStruct SiS300_EModeIDTable[] = { - {0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600x? */ - {0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08}, - {0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x8 */ - {0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00}, - {0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x8 */ - {0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x8 */ - {0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x16 */ - {0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x16 */ - {0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x32 */ - {0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x32 */ - {0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x? */ - {0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x8 */ - {0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */ - {0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, - {0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e}, - {0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23}, - {0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23}, - {0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08}, - {0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08}, - {0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */ - {0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */ - {0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13}, - {0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13}, - {0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a}, - {0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a}, - {0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24}, - {0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */ - {0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26}, - {0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24}, - {0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */ - {0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26}, - {0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23}, - {0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26}, /* TW: inserted 512x384x32 */ - {0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x16 */ - {0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10}, /* TW: inserted 640x400x32 */ - {0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08}, - {0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */ - {0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13}, - {0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a}, - {0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e}, - {0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27}, - {0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27}, - {0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27}, - {0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x8 - not in BIOS! */ - {0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x16 - not in BIOS! */ - {0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x8 */ - {0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x16 */ - /* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */ - {0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x8 */ - {0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x8 */ - {0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x16 */ - {0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x16 */ - {0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x32 */ - {0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x32 */ - {0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x32 */ - {0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x8 */ - {0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x16 */ - /* TW: End of new 16:9 modes */ - {0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x32 */ - {0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, /* 1024x600 */ - {0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, - {0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, - {0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, /* 1152x768 */ - {0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, - {0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, - {0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, /* TW: NEW 1152x864 - not in BIOS */ - {0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, - {0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, - {0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, /* TW: NEW 848x480 - not in BIOS */ - {0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, - {0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, - {0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, /* TW: NEW 856x480 - not in BIOS */ - {0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, - {0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, - {0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, /* TW: NEW 1360x768 - not in BIOS */ - {0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, - {0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, - {0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00} + {0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x? */ + {0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x08}, + {0x2f,0x021b,0x0305,0x0100,SIS_RI_640x400, 0x00,0x00,0x00,0x10}, /* 640x400x8 */ + {0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, + {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x11}, /* 720x480x8 */ + {0x32,0x2a1b,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x12}, /* 720x576x8 */ + {0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x11}, /* 720x480x16 */ + {0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x12}, /* 720x576x16 */ + {0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x11}, /* 720x480x32 */ + {0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x12}, /* 720x576x32 */ + {0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, /* 1024x768x? */ + {0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, /* 1024x768x8 */ + {0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */ + {0x3c,0x063b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, + {0x3d,0x067d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, + {0x40,0x921c,0x0000,0x010d,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x15 */ + {0x41,0x921d,0x0000,0x010e,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x16 */ + {0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480, 0x00,0x00,0x00,0x08}, + {0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480, 0x00,0x00,0x00,0x08}, + {0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x15 */ + {0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x16 */ + {0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, + {0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, + {0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, + {0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, + {0x50,0x921b,0x0001,0x0132,SIS_RI_320x240, 0x00,0x00,0x00,0x24}, /* 320x240x8 */ + {0x51,0xb21b,0x0103,0x0133,SIS_RI_400x300, 0x00,0x00,0x00,0x25}, /* 400x300x8 */ + {0x52,0x921b,0x0204,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x26}, /* 512x384x8 */ + {0x56,0x921d,0x0001,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x24}, /* 320x240x16 */ + {0x57,0xb21d,0x0103,0x0136,SIS_RI_400x300, 0x00,0x00,0x00,0x25}, /* 400x300x16 */ + {0x58,0x921d,0x0204,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x26}, /* 512x384x16 */ + {0x59,0x921b,0x0000,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x8 */ + {0x5c,0x921f,0x0204,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x26}, /* 512x384x32 */ + {0x5d,0x021d,0x0305,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x10}, /* 640x400x16 */ + {0x5e,0x021f,0x0305,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x10}, /* 640x400x32 */ + {0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x08}, + {0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00}, /* 800x600x32 */ + {0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, + {0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, + {0x66,0x06ff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, + {0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x27}, + {0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x27}, + {0x6b,0x07ff,0x080b,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x27}, + {0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28}, /* 2048x1536x8 - not in BIOS! */ + {0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28}, /* 2048x1536x16 - not in BIOS! */ + {0x70,0x2a1b,0x0400,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x2d}, /* 800x480x8 */ + {0x71,0x0a1b,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30}, /* 1024x576x8 */ + {0x74,0x0a1d,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30}, /* 1024x576x16 */ + {0x75,0x0e3d,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33}, /* 1280x720x16 */ + {0x76,0x2a1f,0x0400,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x2d}, /* 800x480x32 */ + {0x77,0x0a3f,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30}, /* 1024x576x32 */ + {0x78,0x0eff,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33}, /* 1280x720x32 */ + {0x79,0x0e3b,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33}, /* 1280x720x8 */ + {0x7a,0x2a1d,0x0400,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x2d}, /* 800x480x16 */ + {0x7c,0x0a3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29}, /* 1280x960x8 */ + {0x7d,0x0a7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29}, /* 1280x960x16 */ + {0x7e,0x0aff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29}, /* 1280x960x32 */ + {0x20,0x0a1b,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b}, /* 1024x600 */ + {0x21,0x0a3d,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b}, + {0x22,0x0a7f,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b}, + {0x23,0x0a1b,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c}, /* 1152x768 */ + {0x24,0x0a3d,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c}, + {0x25,0x0a7f,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c}, + {0x29,0x0e1b,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36}, /* 1152x864 */ + {0x2a,0x0e3d,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36}, + {0x2b,0x0e7f,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36}, + {0x39,0x2a1b,0x0d06,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x38}, /* 848x480 */ + {0x3b,0x2a3d,0x0d06,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x38}, + {0x3e,0x2a7f,0x0d06,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x38}, + {0x3f,0x2a1b,0x0d07,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x3a}, /* 856x480 */ + {0x42,0x2a3d,0x0d07,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x3a}, + {0x45,0x2a7f,0x0d07,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x3a}, + {0x48,0x223b,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c}, /* 1360x768 */ + {0x4b,0x227d,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c}, + {0x4e,0x22ff,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c}, + {0x4f,0x921f,0x0000,0x0000,SIS_RI_320x200, 0x00,0x00,0x00,0x23}, /* 320x200x32 */ + {0x53,0x921f,0x0001,0x0000,SIS_RI_320x240, 0x00,0x00,0x00,0x24}, /* 320x240x32 */ + {0x54,0xb21f,0x0103,0x0000,SIS_RI_400x300, 0x00,0x00,0x00,0x25}, /* 400x300x32 */ + {0x55,0x2e3b,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d}, /* 1280x768 */ + {0x5a,0x2e7d,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d}, + {0x5b,0x2eff,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d}, + {0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x3e}, /* 768x576x8 */ + {0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x3e}, /* 768x576x16 */ + {0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x3e}, /* 768x576x32 */ + {0x67,0x2e3b,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f}, /* 1360x1024x8 (BARCO) */ + {0x6f,0x2e7d,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f}, /* 1360x1024x16 (BARCO) */ + {0x72,0x2eff,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f}, /* 1360x1024x32 (BARCO) */ + {0xff,0x0000,0x0000,0xffff,0x00, 0x00,0x00,0x00,0x00} }; typedef struct _SiS300_Ext2Struct @@ -515,76 +183,77 @@ typedef struct _SiS300_Ext2Struct UCHAR ModeID; USHORT XRes; USHORT YRes; - USHORT ROM_OFFSET; } SiS300_Ext2Struct; static const SiS300_Ext2Struct SiS300_RefIndex[] = { /* TW: Don't ever insert anything here, table is indexed */ - {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */ - {0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */ - {0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */ - {0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */ - {0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */ - {0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */ - {0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */ - {0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */ - {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */ - {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */ - {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */ - {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */ - {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */ - {0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */ - {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */ - {0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */ - {0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */ - {0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */ - {0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */ - {0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */ - {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */ - {0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */ - {0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */ - {0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */ - {0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */ - {0x0047,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */ - {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */ - {0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */ - {0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */ - {0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */ - {0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */ - {0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */ - {0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */ - {0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */ - {0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */ - {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */ - {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */ - {0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */ - {0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */ /* was c077 */ - {0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */ - {0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */ - {0x0027,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */ - {0x0047,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */ - {0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */ - {0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */ /* VCLK 0x09 */ - {0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */ - {0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */ - {0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */ - {0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */ - {0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */ - {0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */ - {0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */ - {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */ - {0x0047,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */ - {0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */ - {0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */ - {0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */ - {0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz - Non-BIOS, new */ - {0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */ - {0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz - Non-BIOS, new */ - {0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */ - {0xffff,0,0,0,0,0,0,0} -}; - -/*add for 300 oem util*/ + {0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 00 */ + {0x0467,0x0e,0x44,0x05,0x6a, 800, 600}, /* 01 */ + {0x0067,0x0f,0x07,0x48,0x6a, 800, 600}, /* 02 - CRT1CRTC was 0x4f */ + {0x0067,0x10,0x06,0x8b,0x6a, 800, 600}, /* 03 */ + {0x0147,0x11,0x08,0x00,0x6a, 800, 600}, /* 04 */ + {0x0147,0x12,0x0c,0x00,0x6a, 800, 600}, /* 05 */ + {0x0047,0x11,0x4e,0x00,0x6a, 800, 600}, /* 06 - CRT1CRTC was 0x51 */ + {0x0047,0x11,0x13,0x00,0x6a, 800, 600}, /* 07 */ + {0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 08 */ + {0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 09 */ + {0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0a */ + {0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0b */ + {0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0c */ + {0xc047,0x0a,0x08,0x00,0x2e, 640, 480}, /* 0d */ + {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480}, /* 0e */ + {0xc047,0x0c,0x10,0x00,0x2e, 640, 480}, /* 0f */ + {0x487f,0x04,0x00,0x00,0x2f, 640, 400}, /* 10 */ + {0xc00f,0x31,0x01,0x06,0x31, 720, 480}, /* 11 */ + {0x000f,0x32,0x03,0x06,0x32, 720, 576}, /* 12 */ + {0x0187,0x15,0x05,0x00,0x37,1024, 768}, /* 13 */ + {0xc877,0x16,0x09,0x06,0x37,1024, 768}, /* 14 */ + {0xc067,0x17,0x0b,0x49,0x37,1024, 768}, /* 15 - CRT1CRTC was 0x97 */ + {0x0267,0x18,0x0d,0x00,0x37,1024, 768}, /* 16 */ + {0x0047,0x19,0x11,0x8c,0x37,1024, 768}, /* 17 - CRT1CRTC was 0x59 */ + {0x0047,0x1a,0x52,0x00,0x37,1024, 768}, /* 18 */ + {0x0007,0x1b,0x16,0x00,0x37,1024, 768}, /* 19 - CRT1CRTC was 0x5b */ + {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024}, /* 1a - CRT1CRTC was 0x5c */ + {0x0077,0x1d,0x14,0x07,0x3a,1280,1024}, /* 1b */ + {0x0047,0x1e,0x17,0x00,0x3a,1280,1024}, /* 1c */ + {0x0007,0x1f,0x98,0x00,0x3a,1280,1024}, /* 1d */ + {0x0007,0x20,0x59,0x00,0x3c,1600,1200}, /* 1e - CRT1CRTC was 0x60 */ + {0x0007,0x21,0x5a,0x00,0x3c,1600,1200}, /* 1f */ + {0x0007,0x22,0x1b,0x00,0x3c,1600,1200}, /* 20 */ + {0x0007,0x23,0x1d,0x00,0x3c,1600,1200}, /* 21 - CRT1CRTC was 0x63 */ + {0x0007,0x24,0x1e,0x00,0x3c,1600,1200}, /* 22 */ + {0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 23 */ + {0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 24 */ + {0x0077,0x02,0x04,0x05,0x51, 400, 300}, /* 25 */ + {0xc877,0x03,0x09,0x06,0x52, 512, 384}, /* 26 */ /* was c077 */ + {0x8207,0x25,0x1f,0x00,0x68,1920,1440}, /* 27 */ + {0x0007,0x26,0x20,0x00,0x6c,2048,1536}, /* 28 */ + {0x0067,0x27,0x14,0x08,0x6e,1280, 960}, /* 29 - TW: 1280x960-60 */ + {0x0027,0x45,0x3c,0x08,0x6e,1280, 960}, /* 2a - TW: 1280x960-85 */ + {0xc077,0x33,0x09,0x06,0x20,1024, 600}, /* 2b */ + {0xc077,0x34,0x0b,0x06,0x23,1152, 768}, /* 2c */ /* VCLK 0x09 */ + {0x0057,0x35,0x27,0x08,0x70, 800, 480}, /* 2d */ + {0x0047,0x36,0x37,0x08,0x70, 800, 480}, /* 2e */ + {0x0047,0x37,0x08,0x08,0x70, 800, 480}, /* 2f */ + {0x0057,0x38,0x09,0x09,0x71,1024, 576}, /* 30 */ + {0x0047,0x39,0x38,0x09,0x71,1024, 576}, /* 31 */ + {0x0047,0x3a,0x11,0x09,0x71,1024, 576}, /* 32 */ + {0x0057,0x3b,0x39,0x0a,0x75,1280, 720}, /* 33 */ + {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720}, /* 34 */ + {0x0007,0x3d,0x3b,0x0a,0x75,1280, 720}, /* 35 */ + {0x0047,0x3e,0x34,0x06,0x29,1152, 864}, /* 36 1152x864-75Hz */ + {0x0047,0x44,0x3a,0x06,0x29,1152, 864}, /* 37 1152x864-85Hz */ + {0x00c7,0x3f,0x28,0x00,0x39, 848, 480}, /* 38 848x480-38Hzi */ + {0xc067,0x40,0x3d,0x0b,0x39, 848, 480}, /* 39 848x480-60Hz */ + {0x00c7,0x41,0x28,0x00,0x3f, 856, 480}, /* 3a 856x480-38Hzi */ + {0xc047,0x42,0x28,0x00,0x3f, 856, 480}, /* 3b 856x480-60Hz */ + {0x0067,0x43,0x3e,0x0c,0x48,1360, 768}, /* 3c 1360x768-60Hz */ + {0x0077,0x46,0x3f,0x08,0x55,1280, 768}, /* 3d 1280x768-60Hz */ + {0x000f,0x47,0x03,0x06,0x5f, 768, 576}, /* 3e 768x576 */ + {0x0027,0x48,0x13,0x08,0x67,1360,1024}, /* 3f 1360x1024-59Hz (BARCO1366 only) */ + {0xffff, 0, 0, 0, 0, 0, 0} +}; + typedef struct _SiS_VBModeIDTableStruct { UCHAR ModeID; @@ -650,9 +319,8 @@ static const SiS_VBModeIDTableStruct SiS300_VBModeIDTable[] = {0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, {0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, {0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, - {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00} /* TW: added! */ + {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }; -/*end*/ typedef struct _SiS300_CRT1TableStruct { @@ -661,15 +329,32 @@ typedef struct _SiS300_CRT1TableStruct static const SiS300_CRT1TableStruct SiS300_CRT1Table[] = { - {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 */ - 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, +#if 1 + {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */ + 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */ + 0x00}}, +#endif +#if 0 + {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f, /* 0x00 - corrected 320x200-72 - does not work */ + 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04, + 0x00}}, +#endif + {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* 0x01 */ + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */ 0x00}}, - {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, - 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, +#if 0 + {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e, /* 0x01 - corrected 320x240-60 - does not work */ + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04, 0x00}}, - {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, +#endif + {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 */ + 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, + 0x01}}, +#if 0 + {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 - corrected 400x300-60 */ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, 0x01}}, +#endif {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, 0x01}}, @@ -842,15 +527,10 @@ static const SiS300_CRT1TableStruct SiS300_CRT1Table[] = {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */ 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02, 0x01}}, -#if 0 - {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, /* 0x34 - 1152x768 */ - 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, - 0x01}}, -#endif - {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - TW: corrected */ + {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - corrected */ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, 0x01}}, - {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 - NEW 16:9 modes, not in BIOS ------ */ + {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 */ 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06, 0x01}}, /* 0x35 */ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba, @@ -865,7 +545,7 @@ static const SiS300_CRT1TableStruct SiS300_CRT1Table[] = {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1, 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02, 0x01}}, /* 0x39 */ - {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* TW: 95 was 15 - illegal HBE! */ + {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */ 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02, 0x01}}, /* 0x3a */ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4, @@ -876,36 +556,40 @@ static const SiS300_CRT1TableStruct SiS300_CRT1Table[] = 0x01}}, /* 0x3c */ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4, 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07, - 0x01}}, /* 0x3d */ /* TW: End of 16:9 modes --------------- */ - {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75 (not in any BIOS) */ + 0x01}}, /* 0x3d */ + {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */ 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07, 0x01}}, /* 0x3e */ - {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */ + {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, 0x00}}, /* 0x3f */ -#if 0 - {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */ - 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, - 0x00}}, /* 0x40 */ -#endif - {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */ + {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */ 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06, 0x00}}, /* 0x40 */ - {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */ + {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, 0x00}}, /* 0x41 */ - {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */ + {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, 0x00}}, /* 0x42 */ - {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */ + {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */ 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03, 0x01}}, /* 0x43 */ - {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84 (not in any BIOS) */ + {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */ 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03, - 0x01}}, /* 0x44 */ - {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85 (not in any BIOS) */ + 0x01}}, /* 0x44 */ + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07, - 0x01}} /* 0x45 */ + 0x01}}, /* 0x45 */ + {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, /* 1280x768-60 */ + 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07, + 0x01}}, /* 0x46 */ + {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */ + 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, + 0x01}}, /* 0x47 */ + {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52, /* 1360x1024 (Barco iQ Pro R300) */ + 0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03, + 0x00}} /* 0x48 */ }; typedef struct _SiS300_MCLKDataStruct @@ -914,8 +598,8 @@ typedef struct _SiS300_MCLKDataStruct USHORT CLOCK; } SiS300_MCLKDataStruct; -static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] = /* 630 */ -{ /* TW: at 0x54 in BIOS */ +static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] = +{ { 0x5a,0x64,0x80, 66}, { 0xb3,0x45,0x80, 83}, { 0x37,0x61,0x80,100}, @@ -926,8 +610,8 @@ static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] = /* 630 */ { 0x37,0x61,0x80,100} }; -static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] = /* 300 */ -{ /* TW: at 0x54 in BIOS */ +static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] = +{ { 0x68,0x43,0x80,125}, { 0x68,0x43,0x80,125}, { 0x68,0x43,0x80,125}, @@ -938,6 +622,7 @@ static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] = /* 300 */ { 0x37,0x61,0x80,100} }; +#ifdef LINUXBIOS typedef struct _SiS300_ECLKDataStruct { UCHAR SR2E,SR2F,SR30; @@ -955,6 +640,7 @@ static const SiS300_ECLKDataStruct SiS300_ECLKData[] = { 0x54,0x43,0x80,100}, { 0x54,0x43,0x80,100} }; +#endif typedef struct _SiS300_VCLKDataStruct { @@ -965,71 +651,77 @@ typedef struct _SiS300_VCLKDataStruct static const SiS300_VCLKDataStruct SiS300_VCLKData[] = { { 0x1b,0xe1, 25}, /* 0x00 */ - { 0x4e,0xe4, 28}, + { 0x4e,0xe4, 28}, /* 0x01 */ { 0x57,0xe4, 32}, /* 0x02 */ - { 0xc3,0xc8, 36}, + { 0xc3,0xc8, 36}, /* 0x03 */ { 0x42,0xc3, 40}, /* 0x04 */ - { 0x5d,0xc4, 45}, + { 0x5d,0xc4, 45}, /* 0x05 */ { 0x52,0x65, 50}, /* 0x06 */ - { 0x53,0x65, 50}, + { 0x53,0x65, 50}, /* 0x07 */ { 0x6d,0x66, 56}, /* 0x08 */ - { 0x5a,0x64, 65}, + { 0x5a,0x64, 65}, /* 0x09 */ { 0x46,0x44, 68}, /* 0x0a */ - { 0x3e,0x43, 75}, - { 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */ - { 0x41,0x43, 79}, + { 0x3e,0x43, 75}, /* 0x0b */ + { 0x6d,0x46, 76}, /* 0x0c */ /* 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */ + { 0x41,0x43, 79}, /* 0x0d */ { 0x31,0x42, 79}, /* 0x0e */ - { 0x46,0x25, 85}, + { 0x46,0x25, 85}, /* 0x0f */ { 0x78,0x29, 87}, /* 0x10 */ - { 0x62,0x44, 95}, + { 0x62,0x44, 95}, /* 0x11 */ { 0x2b,0x22,105}, /* 0x12 */ - { 0x49,0x24,106}, + { 0x49,0x24,106}, /* 0x13 */ { 0xc3,0x28,108}, /* 0x14 */ - { 0x3c,0x23,109}, + { 0x3c,0x23,109}, /* 0x15 */ { 0xf7,0x2c,132}, /* 0x16 */ - { 0xd4,0x28,136}, + { 0xd4,0x28,136}, /* 0x17 */ { 0x41,0x05,158}, /* 0x18 */ - { 0x43,0x05,162}, + { 0x43,0x05,162}, /* 0x19 */ { 0xe1,0x0f,175}, /* 0x1a */ { 0xfc,0x12,189}, /* 0x1b */ { 0xde,0x26,194}, /* 0x1c */ - { 0x54,0x05,203}, + { 0x54,0x05,203}, /* 0x1d */ { 0x3f,0x03,230}, /* 0x1e */ - { 0x30,0x02,234}, + { 0x30,0x02,234}, /* 0x1f */ { 0x24,0x01,266}, /* 0x20 */ - { 0x52,0x2a, 54}, /* 301 TV */ - { 0x52,0x6a, 27}, /* 301 TV */ - { 0x62,0x24, 70}, /* 301 TV */ - { 0x62,0x64, 70}, /* 301 TV */ - { 0xa8,0x4c, 30}, /* 301 TV */ - { 0x20,0x26, 33}, /* 301 TV */ - { 0x31,0xc2, 39}, - { 0xbf,0xc8, 35}, /* 0x28 - 856x480 */ - { 0x60,0x36, 30}, /* 0x29 CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */ - { 0x40,0x4a, 28}, - { 0x9f,0x46, 44}, - { 0x97,0x2c, 26}, - { 0x44,0xe4, 25}, - { 0x7e,0x32, 47}, - { 0x8a,0x24, 31}, /* 0x2f CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */ - { 0x97,0x2c, 26}, - { 0xce,0x3c, 39}, - { 0x52,0x4a, 36}, /* 0x32 CH/PAL 800x600 5/6 */ - { 0x34,0x61, 95}, - { 0x78,0x27,108}, - { 0xce,0x25,189}, /* 0x35 */ - { 0x45,0x6b, 21}, /* 0x36 */ /* TW: Added from Mitac */ - { 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */ - { 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */ - { 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */ - { 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */ - { 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */ - { 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/ - { 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */ - { 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/ - { 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/ - { 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */ - { 0x15,0x21, 79}, /* 0x41 - test for SiS730 */ + { 0x52,0x2a, 54}, /* 0x21 */ /* 301 TV */ + { 0x52,0x6a, 27}, /* 0x22 */ /* 301 TV */ + { 0x62,0x24, 70}, /* 0x23 */ /* 301 TV */ + { 0x62,0x64, 70}, /* 0x24 */ /* 301 TV */ + { 0xa8,0x4c, 30}, /* 0x25 */ /* 301 TV */ + { 0x20,0x26, 33}, /* 0x26 */ /* 301 TV */ + { 0x31,0xc2, 39}, /* 0x27 */ + { 0xbf,0xc8, 35}, /* 0x28 */ /* 856x480 */ + { 0x60,0x36, 30}, /* 0x29 */ /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */ + { 0x40,0x4a, 28}, /* 0x2a */ /* CH-TV */ + { 0x9f,0x46, 44}, /* 0x2b */ /* CH-TV */ + { 0x97,0x2c, 26}, /* 0x2c */ /* CH-TV */ + { 0x44,0xe4, 25}, /* 0x2d */ /* CH-TV */ + { 0x7e,0x32, 47}, /* 0x2e */ /* CH-TV */ + { 0x8a,0x24, 31}, /* 0x2f */ /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */ + { 0x97,0x2c, 26}, /* 0x30 */ /* CH-TV */ + { 0xce,0x3c, 39}, /* 0x31 */ /* CH-TV */ + { 0x52,0x4a, 36}, /* 0x32 */ /* CH/PAL 800x600 5/6 */ + { 0x34,0x61, 95}, /* 0x33 */ + { 0x78,0x27,108}, /* 0x34 */ /* Replacement for index 0x14 for 630 (?) */ + { 0xce,0x25,189}, /* 0x35 */ /* Replacement for index 0x1b for 730 (and 540?) */ + { 0x45,0x6b, 21}, /* 0x36 */ /* Chrontel SuperOverscan */ + { 0x52,0xe2, 49}, /* 0x37 */ /* 16:9 modes */ + { 0x2b,0x61, 78}, /* 0x38 */ /* 16:9 modes */ + { 0x70,0x44,108}, /* 0x39 */ /* 16:9 modes */ + { 0x54,0x42,135}, /* 0x3a */ /* 16:9 modes */ + { 0x41,0x22,157}, /* 0x3b */ /* 16:9 modes */ + { 0x52,0x07,149}, /* 0x3c */ /* 1280x960-85 */ + { 0x62,0xc6, 34}, /* 0x3d */ /* 848x480-60 */ + { 0x30,0x23, 88}, /* 0x3e */ /* 1360x768-60 */ +#if 0 + { 0x3f,0x64, 46}, /* 0x3f */ /* 640x480-100 */ +#endif + { 0x70,0x29, 81}, /* 0x3f */ /* 1280x768-60 */ + { 0x72,0x2a, 76}, /* 0x40 */ /* test for SiS730 */ + { 0x15,0x21, 79}, /* 0x41 */ /* test for SiS730 */ + { 0xa1,0x42,108}, /* 0x42 */ /* 1280x960 LCD */ + { 0x37,0x61,100}, /* 0x43 */ /* 1280x960 LCD */ + { 0xe3,0x9a,106}, /* 0x44 */ /* 1360x1024 - special for Barco iQ R300 */ { 0xff,0x00, 0} }; @@ -1090,65 +782,9 @@ static const SiS300_VCLKDataStruct SiS300_VBVCLKData[] = static const UCHAR SiS300_ScreenOffset[] = { 0x14,0x19,0x20,0x28,0x32,0x40,0x50, - 0x64,0x78,0x80,0x2d,0x35,0x48,0x35, /* 0x35 for 848 and 856 */ - 0x55,0xff /* 0x55 for 1360 */ -}; - -typedef struct _SiS300_StResInfoStruct -{ - USHORT HTotal; - USHORT VTotal; -} SiS300_StResInfoStruct; - -static const SiS300_StResInfoStruct SiS300_StResInfo[] = -{ - { 640,400}, - { 640,350}, - { 720,400}, - { 720,350}, - { 640,480} -}; - -typedef struct _SiS300_ModeResInfoStruct -{ - USHORT HTotal; - USHORT VTotal; - UCHAR XChar; - UCHAR YChar; -} SiS300_ModeResInfoStruct; - -static const SiS300_ModeResInfoStruct SiS300_ModeResInfo[] = -{ - { 320, 200, 8, 8}, /* 0x00 */ - { 320, 240, 8, 8}, /* 0x01 */ - { 320, 400, 8, 8}, /* 0x02 */ - { 400, 300, 8, 8}, /* 0x03 */ - { 512, 384, 8, 8}, /* 0x04 */ - { 640, 400, 8,16}, /* 0x05 */ - { 640, 480, 8,16}, /* 0x06 */ - { 800, 600, 8,16}, /* 0x07 */ - { 1024, 768, 8,16}, /* 0x08 */ - { 1280,1024, 8,16}, /* 0x09 */ - { 1600,1200, 8,16}, /* 0x0a */ - { 1920,1440, 8,16}, /* 0x0b */ - { 720, 480, 8,16}, /* 0x0c */ - { 720, 576, 8,16}, /* 0x0d */ - { 1280, 960, 8,16}, /* 0x0e */ - { 1024, 600, 8,16}, /* 0x0f */ - { 1152, 768, 8,16}, /* 0x10 */ - { 2048,1536, 8,16}, /* 0x11 - TW: Not in BIOS! */ - { 800, 480, 8,16}, /* 0x12 - TW: New, not in any BIOS */ - { 1024, 576, 8,16}, /* 0x13 - TW: New, not in any BIOS */ - { 1280, 720, 8,16}, /* 0x14 - TW: New, not in any BIOS */ - { 1152, 864, 8,16}, /* 0x15 - TW: New, not in any BIOS */ - { 848, 480, 8,16}, /* 0x16 - TW: New, not in any BIOS */ - { 856, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */ - { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */ -}; - -static const UCHAR SiS300_OutputSelect = 0x40; - -static const UCHAR SiS300_SoftSetting = 0x30; + 0x64,0x78,0x80,0x2d,0x35,0x48,0x35, + 0x55,0x30,0xff +}; #ifndef LINUX_XF86 static UCHAR SiS300_SR07 = 0x10; @@ -1184,7 +820,7 @@ static UCHAR SiS300_CRT2Data_4_10 = 0x80; static const USHORT SiS300_RGBSenseData = 0xd1; static const USHORT SiS300_VideoSenseData = 0xb3; static const USHORT SiS300_YCSenseData = 0xb9; -static const USHORT SiS300_RGBSenseData2 = 0x0190; /*301b*/ +static const USHORT SiS300_RGBSenseData2 = 0x0190; static const USHORT SiS300_VideoSenseData2 = 0x0174; static const USHORT SiS300_YCSenseData2 = 0x016b; @@ -1193,15 +829,6 @@ static const UCHAR SiS300_CR40[5][4]; static UCHAR SiS300_CR49[2]; #endif -static const UCHAR SiS300_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */ -static const UCHAR SiS300_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */ -static const UCHAR SiS300_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* palmn */ -static const UCHAR SiS300_PALNPhase[] = {0x21,0xF4,0x3E,0xBA}; -static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6}; /* 301b */ -static const UCHAR SiS300_PALPhase2[] = {0x2a,0x09,0x86,0xe9}; /* 301b */ -static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/ -static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/ - typedef struct _SiS300_PanelDelayTblStruct { UCHAR timer[2]; @@ -1209,7 +836,7 @@ typedef struct _SiS300_PanelDelayTblStruct static const SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] = { - {{0x05,0xaa}}, /* TW: From 2.04.5a */ + {{0x05,0xaa}}, {{0x05,0x14}}, {{0x05,0x36}}, {{0x05,0x14}}, @@ -1356,294 +983,6 @@ static const SiS300_LCDDataStruct SiS300_NoScaleData1280x1024[] = /* TW: Fake { 1, 1,1688,1066,1688,1066} }; -static const SiS300_LCDDataStruct SiS300_LCD1280x960Data[] = -{ - { 9, 2, 800, 500,1800,1000}, - { 9, 2, 800, 500,1800,1000}, - { 4, 1, 900, 500,1800,1000}, - { 4, 1, 900, 500,1800,1000}, - { 9, 2, 800, 500,1800,1000}, - { 30, 11,1056, 625,1800,1000}, - { 5, 3,1350, 800,1800,1000}, - { 1, 1,1576,1050,1576,1050}, - { 1, 1,1800,1000,1800,1000} -}; - -static const SiS300_LCDDataStruct SiS300_ExtLCD1400x1050Data[] = /* TW: New */ -{ - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0} -}; - -static const SiS300_LCDDataStruct SiS300_ExtLCD1600x1200Data[] = /* TW: New */ -{ - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0} -}; - -static const SiS300_LCDDataStruct SiS300_StLCD1400x1050Data[] = /* TW: New */ -{ - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0} -}; - -static const SiS300_LCDDataStruct SiS300_StLCD1600x1200Data[] = /* TW: New */ -{ - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0} -}; - -static const SiS300_LCDDataStruct SiS300_NoScaleData1400x1050[] = /* TW: New */ -{ - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0} -}; - -static const SiS300_LCDDataStruct SiS300_NoScaleData1600x1200[] = /* TW: New */ -{ - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0} -}; - - -typedef struct _SiS300_TVDataStruct -{ - USHORT RVBHCMAX; - USHORT RVBHCFACT; - USHORT VGAHT; - USHORT VGAVT; - USHORT TVHDE; - USHORT TVVDE; - USHORT RVBHRS; - UCHAR FlickerMode; - USHORT HALFRVBHRS; - UCHAR RY1COE; - UCHAR RY2COE; - UCHAR RY3COE; - UCHAR RY4COE; -} SiS300_TVDataStruct; - -static const SiS300_TVDataStruct SiS300_StPALData[] = -{ - { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22}, - { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22}, - { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, - { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, - { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22}, - { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22} -}; - -static const SiS300_TVDataStruct SiS300_ExtPALData[] = -{ - { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, - { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, - { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18}, - { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a}, - { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, - { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, - { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, - { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} - -}; - -static const SiS300_TVDataStruct SiS300_StNTSCData[] = -{ - { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18}, - { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18}, - { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, - { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, - { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18} -}; - -static const SiS300_TVDataStruct SiS300_ExtNTSCData[] = -{ - { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, - { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, - { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18}, - { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a}, - { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, - { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, - { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, - { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xf1,0x04,0x1f,0x18} -}; - -static const SiS_TVDataStruct SiS300_St1HiTVData[] = -{ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} -}; - -static const SiS_TVDataStruct SiS300_St2HiTVData[] = -{ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} -}; - -static const SiS_TVDataStruct SiS300_ExtHiTVData[] = -{ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} -}; - -static const UCHAR SiS300_NTSCTiming[] = -{ - 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, - 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, - 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b, - 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, /* (in 2.06.50) */ -/* 0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17, (in 2.04.5a) */ - 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, /* (in 2.06.50) */ -/* 0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02, (in 2.04.5a) */ - 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50, - 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 -}; - -static const UCHAR SiS300_PALTiming[] = -{ - 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70, - 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b, - 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17, /* (in 2.06.50) */ -/* 0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17, (in 2.04.5a) */ - 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02, /* (in 2.06.50) */ -/* 0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02, (in 2.04.5a) */ - 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63, - 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00 -}; - -#ifdef oldHV -static const UCHAR SiS300_HiTVExtTiming[] = /* TW: New */ -{ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, - 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, - 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, - 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 -}; - -static const UCHAR SiS300_HiTVSt1Timing[] = /* TW: New */ -{ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03, - 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10, - 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86, - 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00 -}; - -static const UCHAR SiS300_HiTVSt2Timing[] = /* TW: New */ -{ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, - 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, - 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, - 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 -}; - -static const UCHAR SiS300_HiTVTextTiming[] = /* TW: New */ -{ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03, - 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20, - 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96, - 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00 -}; - -static const UCHAR SiS300_HiTVGroup3Data[] = /* TW: New */ -{ - 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f, - 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6, - 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, - 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44, - 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, - 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9, - 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75, - 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 -}; - -static const UCHAR SiS300_HiTVGroup3Simu[] = /* TW: New */ -{ - 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95, - 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6, - 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, - 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11, - 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, - 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4, - 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, - 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 -}; - -static const UCHAR SiS300_HiTVGroup3Text[] = /* TW: New */ -{ - 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7, - 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6, - 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, - 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22, - 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, - 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca, - 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, - 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 -}; -#endif - typedef struct _SiS300_LVDSDataStruct { USHORT VGAHT; @@ -1652,342 +991,14 @@ typedef struct _SiS300_LVDSDataStruct USHORT LCDVT; } SiS300_LVDSDataStruct; -static const SiS300_LVDSDataStruct SiS300_LVDS320x480Data_1[] = -{ - {848, 433,400, 525}, - {848, 389,400, 525}, - {848, 433,400, 525}, - {848, 389,400, 525}, - {848, 518,400, 525}, - {1056,628,400, 525}, - {400, 525,400, 525}, - {800, 449,1000, 644}, - {800, 525,1000, 635} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_1[] = -{ - {848, 433,1060, 629}, - {848, 389,1060, 629}, - {848, 433,1060, 629}, - {848, 389,1060, 629}, - {848, 518,1060, 629}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {800, 449,1000, 644}, - {800, 525,1000, 635} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_2[] = -{ - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {800, 449,1000, 644}, - {800, 525,1000, 635} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_1[] = -{ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_2[] = -{ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_1[] = -{ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_2[] = -{ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_1[] = /* TW: New */ -{ - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 496, 1688, 1066}, - {1088, 616, 1688, 1066}, - {1312, 784, 1688, 1066}, - {1568, 1040, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_2[] = /* TW: New */ -{ - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_1[]= /* TW: New - TODO */ -{ /* TW: Temp data, invalid (is identical to 1024x768) */ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_2[]= /* TW: New - TODO */ -{ /* TW: Temp data, invalid (is identical to 1024x768) */ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New: */ -static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_1[] = -{ - {840, 604,1344, 800}, - {840, 560,1344, 800}, - {840, 604,1344, 800}, - {840, 560,1344, 800}, - {840, 689,1344, 800}, - {1050, 800,1344, 800}, - {1344, 800,1344, 800}, - {800, 449,1280, 789}, - {800, 525,1280, 785} -}; - -/* TW: New: */ -static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_2[] = -{ - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New: */ -static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_1[] = -{ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New: */ -static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_2[] = -{ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New in 650/LVDS BIOS - 1:1 */ -static const SiS300_LVDSDataStruct SiS300_LVDSXXXxXXXData_1[] = /* TW: New */ -{ - { 800, 449, 800, 449}, - { 800, 449, 800, 449}, - { 900, 449, 900, 449}, - { 900, 449, 900, 449}, - { 800, 525, 800, 525}, - {1056, 628,1056, 628}, - {1344, 806,1344, 806}, - {1688, 806,1688, 806} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS640x480Data_1[] = -{ - {800, 449, 800, 449}, - {800, 449, 800, 449}, - {800, 449, 800, 449}, - {800, 449, 800, 449}, - {800, 525, 800, 525}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_1[] = /* TW: New */ -{ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_2[] = /* TW: New */ -{ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_1[] = /* TW: New */ -{ /* TW: Might be temporary (invalid) data */ - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {1008, 416, 1688, 1066}, - {1008, 366, 1688, 1066}, - {1200, 530, 1688, 1066}, - {1088, 616, 1688, 1066}, - {1312, 784, 1688, 1066}, - {1568, 1040, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_2[] = /* TW: New */ -{ /* TW: Temporary data. Not valid */ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_1[] = /* TW: New */ -{ /* TW: Temporary data. Not valid */ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_2[] = /* TW: New */ -{ /* TW: Temporary data. Not valid */ - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - - -/* TW: New: */ -static const SiS300_LVDSDataStruct SiS300_CHTVUNTSCData[] = -{ - {840, 600, 840, 600}, - {840, 600, 840, 600}, - {840, 600, 840, 600}, - {840, 600, 840, 600}, - {784, 600, 784, 600}, - {1064, 750,1064, 750} -}; - -static const SiS300_LVDSDataStruct SiS300_CHTVONTSCData[] = -{ - {840, 525, 840, 525}, - {840, 525, 840, 525}, - {840, 525, 840, 525}, - {840, 525, 840, 525}, - {784, 525, 784, 525}, - {1040, 700,1040, 700} -}; - static const SiS300_LVDSDataStruct SiS300_CHTVUPALData[] = { {1008, 625,1008, 625}, {1008, 625,1008, 625}, {1008, 625,1008, 625}, {1008, 625,1008, 625}, - {840, 750, 840, 750}, - {936, 836, 936, 836} + { 840, 750, 840, 750}, + { 936, 836, 936, 836} }; static const SiS300_LVDSDataStruct SiS300_CHTVOPALData[] = @@ -1996,8 +1007,8 @@ static const SiS300_LVDSDataStruct SiS300_CHTVOPALData[] = {1008, 625,1008, 625}, {1008, 625,1008, 625}, {1008, 625,1008, 625}, - {840, 625, 840, 625}, - {960, 750, 960, 750} + { 840, 625, 840, 625}, + { 960, 750, 960, 750} }; static const SiS300_LVDSDataStruct SiS300_CHTVSOPALData[] = @@ -2006,12 +1017,10 @@ static const SiS300_LVDSDataStruct SiS300_CHTVSOPALData[] = {1008, 625,1008, 625}, {1008, 625,1008, 625}, {1008, 625,1008, 625}, - {840, 500, 840, 500}, - {944, 625, 944, 625} + { 840, 500, 840, 500}, + { 944, 625, 944, 625} }; -/* TW: new end */ - typedef struct _SiS300_LVDSDesStruct { USHORT LCDHDES; @@ -2020,57 +1029,90 @@ typedef struct _SiS300_LVDSDesStruct static const SiS300_LVDSDesStruct SiS300_PanelType00_1[] = { + { 1059, 626 }, /* 2.08 */ + { 1059, 624 }, + { 1059, 626 }, + { 1059, 624 }, + { 1059, 624 }, + { 0, 627 }, + { 0, 627 }, + { 0, 0 }, + { 0, 0 } +#if 0 {0, 626}, {0, 624}, {0, 626}, {0, 624}, {0, 624}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + {0, 627}, + {0, 627}, + {0, 0}, + {0, 0} +#endif }; static const SiS300_LVDSDesStruct SiS300_PanelType01_1[] = { + { 0, 0 }, /* 2.08 */ + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 } +#if 0 {1343, 798}, {1343, 794}, {1343, 798}, {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} +#endif }; static const SiS300_LVDSDesStruct SiS300_PanelType02_1[] = { + { 1059, 626 }, /* 2.08 */ + { 1059, 624 }, + { 1059, 626 }, + { 1059, 624 }, + { 1059, 624 }, + { 0, 627 }, + { 0, 627 }, + { 0, 0 }, + { 0, 0 } +#if 0 {0, 626}, {0, 624}, {0, 626}, {0, 624}, {0, 624}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + {0, 627}, + {0, 627}, + {0, 0}, + {0, 0} +#endif }; static const SiS300_LVDSDesStruct SiS300_PanelType03_1[] = { - { 8, 436}, - { 8, 440}, - { 8, 436}, - { 8, 440}, - { 8, 512}, + { 8, 436}, + { 8, 440}, + { 8, 436}, + { 8, 440}, + { 8, 512}, {1343, 798}, {1343, 794}, {1343, 798}, {1343, 794} }; -static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] = +static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] = /* 1280x1024 */ { {1343, 798}, {1343, 794}, @@ -2078,9 +1120,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType05_1[] = @@ -2091,9 +1133,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType05_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType06_1[] = @@ -2104,9 +1146,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType06_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType07_1[] = @@ -2117,9 +1159,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType07_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType08_1[] = @@ -2129,10 +1171,10 @@ static const SiS300_LVDSDesStruct SiS300_PanelType08_1[] = {1059, 626}, {1059, 624}, {1059, 624}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType09_1[] = @@ -2143,9 +1185,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType09_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType0a_1[] = @@ -2155,23 +1197,23 @@ static const SiS300_LVDSDesStruct SiS300_PanelType0a_1[] = {1059, 626}, {1059, 624}, {1059, 624}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType0b_1[] = { - {1343, 0}, - {1343, 0}, - {1343, 0}, - {1343, 0}, - {1343, 0}, /* 640x480 - BIOS 1343, 0 */ - {1343, 0}, - { 0, 799}, - { 0, 0}, - { 0, 0} + {1343, 0}, + {1343, 0}, + {1343, 0}, + {1343, 0}, + {1343, 0}, + {1343, 0}, + { 0, 799}, + { 0, 0}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType0c_1[] = @@ -2182,9 +1224,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType0c_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType0d_1[] = @@ -2195,9 +1237,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType0d_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType0e_1[] = @@ -2206,11 +1248,11 @@ static const SiS300_LVDSDesStruct SiS300_PanelType0e_1[] = {1343, 794}, {1343, 798}, {1343, 794}, - {1343, 0}, /* 640x480 */ - {1343, 0}, /* 800x600 */ - { 0, 805}, /* 1024x768 */ - { 0, 794}, /* 1280x1024 */ - { 0, 0} /* 1280x960 - not applicable */ + {1343, 0}, /* 640x480 */ + {1343, 0}, /* 800x600 */ + { 0, 805}, /* 1024x768 */ + { 0, 794}, /* 1280x1024 */ + { 0, 0} /* 1280x960 - not applicable */ }; static const SiS300_LVDSDesStruct SiS300_PanelType0f_1[] = @@ -2221,9 +1263,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType0f_1[] = {1343, 794}, {1343, 0}, {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType00_2[] = @@ -2233,10 +1275,10 @@ static const SiS300_LVDSDesStruct SiS300_PanelType00_2[] = {976, 527}, {976, 502}, {976, 567}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType01_2[] = @@ -2247,9 +1289,9 @@ static const SiS300_LVDSDesStruct SiS300_PanelType01_2[] = {1152, 597}, {1152, 662}, {1232, 722}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 805}, + { 0, 794}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType02_2[] = @@ -2259,10 +1301,10 @@ static const SiS300_LVDSDesStruct SiS300_PanelType02_2[] = {976, 527}, {976, 502}, {976, 567}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} }; static const SiS300_LVDSDesStruct SiS300_PanelType03_2[] = @@ -2434,128 +1476,57 @@ static const SiS300_LVDSDesStruct SiS300_PanelType0f_2[] = { 0, 0} }; -static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] = /* TW: New */ -{ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] = /* TW: New */ -{ - { 1152, 622 }, - { 1152, 597 }, - { 1152, 622 }, - { 1152, 597 }, - { 1152, 622 }, - { 1232, 722 }, - { 0, 0 }, - { 0, 794 }, - { 0, 0 } -}; - -static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] = /* TW: New */ -{ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] = /* TW: New */ -{ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] = /* TW: New */ +/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */ +static const SiS300_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */ { - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} + {1330, 798}, /* 320x200 */ + {1330, 794}, + {1330, 798}, + {1330, 794}, + {1330, 0}, /* 640x480 / 320x240 */ + {1343, 0}, /* 800x600 / 400x300 */ + { 0, 805}, /* 1024x768 / 512x384 */ + {1688,1066}, /* 1280x1024 */ + { 0, 0} /* 1360x1024 */ }; -static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] = /* TW: New */ +static const SiS300_LVDSDesStruct SiS300_PanelType04_2a[] = { - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - - -/* TW: New */ -static const SiS300_LVDSDesStruct SiS300_CHTVUNTSCDesData[] = -{ - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0} + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + {1688,1066}, + { 0, 0} }; -static const SiS300_LVDSDesStruct SiS300_CHTVONTSCDesData[] = +/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */ +static const SiS300_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */ { - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0} + {1330, 798}, /* 320x200 */ + {1330, 794}, + {1330, 798}, + {1330, 794}, + {1330, 0}, /* 640x480 / 320x240 */ + {1343, 0}, /* 800x600 / 400x300 */ + { 0, 805} /* 1024x768 / 512x384 */ }; -static const SiS300_LVDSDesStruct SiS300_CHTVUPALDesData[] = +static const SiS300_LVDSDesStruct SiS300_PanelType04_2b[] = { - {256, 0}, - {256, 0}, - {256, 0}, - {256, 0}, - { 0, 0}, - { 0, 0} + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805} }; -static const SiS300_LVDSDesStruct SiS300_CHTVOPALDesData[] = -{ - {256, 0}, - {256, 0}, - {256, 0}, - {256, 0}, - { 0, 0}, - { 0, 0} -}; -/* TW: New end */ -/* TW: New for SiS300+301LV */ typedef struct _SiS300_Part2PortTblStruct { UCHAR CR[12]; @@ -2660,6 +1631,28 @@ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] = 0x01 }} }; +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] = +{ + {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04, + 0x00 }}, + {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x05, + 0x01 }} +}; + static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] = { {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, @@ -2685,55 +1678,31 @@ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] = 0x01}} }; -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] = -{ - {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, - 0x00 }}, - {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, - 0x00 }}, - {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, - 0x00 }}, - {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, - 0x00 }}, - {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e, - 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, - 0x00 }}, - {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, - 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, - 0x01 }}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, - 0x01 }} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] = +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] = { - {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f, - 0x90,0x85,0x8f,0xab,0x30,0x00,0x04, - 0x00 }}, - {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f, - 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04, - 0x00 }}, - {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f, - 0x90,0x85,0x8f,0xab,0x30,0x00,0x04, - 0x00 }}, - {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f, - 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04, - 0x00 }}, - {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e, - 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, 0x00 }}, - {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0, - 0x58,0x8c,0x57,0x73,0x20,0x00,0x05, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5D,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5D,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xE2,0x89,0xdf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, 0x01 }} -}; -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] = -{ +#if 0 {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f, 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, 0x00 }}, @@ -2755,6 +1724,32 @@ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] = {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5, 0x02,0x88,0xFf,0x25,0x10,0x00,0x01, 0x01 }} +#endif +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] = +{ + {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, + 0x00 }}, + {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, + 0x01 }}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01 }} }; static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] = @@ -2804,32 +1799,29 @@ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] = 0x01 }} }; -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] = +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] = { - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, + 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05, 0x00 }}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, + 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05, 0x00 }}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, + 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05, 0x00 }}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e, + 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05, 0x00 }}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba, + 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05, 0x00 }}, - {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x02, - 0x01 }}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x05, 0x01 }} }; -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] = +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] = { {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, @@ -2854,28 +1846,6 @@ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] = 0x01 }} }; -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] = -{ - {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, - 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05, - 0x00 }}, - {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, - 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05, - 0x00 }}, - {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, - 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05, - 0x00 }}, - {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e, - 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05, - 0x00 }}, - {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba, - 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05, - 0x00 }}, - {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0, - 0x58,0x8c,0x57,0x73,0x20,0x00,0x05, - 0x01 }} -}; - static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] = { {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, @@ -2901,6 +1871,31 @@ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] = 0x01 }} }; +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01 }}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01 }} +}; + static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] = { {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb, @@ -2926,207 +1921,6 @@ static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] = 0x01}} }; -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1[] = -{ - {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, - 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, - 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, - 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, - 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba, - 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01, - 0x00}}, - {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1, - 0xae,0x85,0x57,0x1f,0x30,0x00,0x26, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1, - 0xae,0x85,0x57,0x1f,0x30,0x00,0x02, - 0x01}} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1_H[] = -{ - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, - 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, - 0x00}}, - {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, - 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2[] = -{ - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x02, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, - 0x01}} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2_H[] = -{ - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x01, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1[] = -{ - {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e, - 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, - 0x00}}, - {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, - 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, - 0x01}} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1_H[] = -{ - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, - 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, - 0x00}}, - {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, - 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2[] = -{ - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x02, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, - 0x01}} -}; - -static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2_H[] = -{ - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x01, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -/* TW: New */ static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] = { {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, @@ -3236,9 +2030,7 @@ static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] = 0x90,0x8c,0x57,0xed,0x20,0x00,0x05, 0x01 }} }; -/* TW: New end */ -/* TW: New */ typedef struct _SiS300_CHTVRegDataStruct { UCHAR Reg[16]; @@ -3288,16 +2080,14 @@ static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] = static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] = { - {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 5/4 */ + {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */ {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */ {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* TW: Mode 19: 800x600 PAL 1/1 */ }; -/* TW: New end */ -/* TW: New */ static const UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e}; static const UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b}; @@ -3309,6 +2099,5 @@ static const UCHAR SiS300_CHTVVCLKUPAL[] = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31}; static const UCHAR SiS300_CHTVVCLKOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x30,0x32}; static const UCHAR SiS300_CHTVVCLKSOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x36,0x29}; -/* TW: New end */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h index 5bb9d772a..42c597a90 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h @@ -1,8 +1,37 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h,v 1.5 2003/02/10 01:14:16 tsi Exp $ */ - - -/* Register settings for SiS 310/325 series */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h,v 1.12 2003/08/07 12:52:22 twini Exp $ */ +/* + * Register settings for SiS 315/330 series + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * Based on code by Silicon Intergrated Systems + * + */ typedef struct _SiS310_StStruct { @@ -40,465 +69,12 @@ static const SiS310_StStruct SiS310_SModeIDTable[]= {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00} }; -typedef struct _SiS310_StandTableStruct -{ - UCHAR CRT_COLS; - UCHAR ROWS; - UCHAR CHAR_HEIGHT; - USHORT CRT_LEN; - UCHAR SR[4]; - UCHAR MISC; - UCHAR CRTC[0x19]; - UCHAR ATTR[0x14]; - UCHAR GRC[9]; -} SiS310_StandTableStruct; - -static const SiS310_StandTableStruct SiS310_StandTable[]= -{ -/* MD_0_200 */ - { - 0x28,0x18,0x08,0x0800, - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_1_200 */ - { - 0x28,0x18,0x08,0x0800, - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_2_200 */ - { - 0x50,0x18,0x08,0x1000, - {0x01,0x03,0x00,0x02}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_3_200 */ - { - 0x50,0x18,0x08,0x1000, - {0x01,0x03,0x00,0x02}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_4 */ - { - 0x28,0x18,0x08,0x4000, - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, - 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, - 0xff}, - {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x03,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, - 0xff} - }, -/* MD_5 */ - { - 0x28,0x18,0x08,0x4000, - {0x09,0x03,0x00,0x02}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, - 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, - 0xff}, - {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x03,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, - 0xff} - }, -/* MD_6 */ - { - 0x50,0x18,0x08,0x4000, - {0x01,0x01,0x00,0x06}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2, - 0xff}, - {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17, - 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, - 0x01,0x00,0x01,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00, - 0xff} - }, -/* MD_7 */ - { - 0x50,0x18,0x0e,0x1000, - {0x00,0x03,0x00,0x03}, - 0xa6, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3, - 0xff}, - {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, - 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, - 0x0e,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, - 0xff} - }, -/* MDA_DAC */ - { - 0x00,0x00,0x00,0x0000, - {0x00,0x00,0x00,0x15}, - 0x15, - {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, - 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f, - 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00, - 0x00}, - {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15, - 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, - 0x15,0x15,0x15,0x15}, - {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, - 0x3f} - }, -/* CGA_DAC */ - { - 0x00,0x10,0x04,0x0114, - {0x11,0x09,0x15,0x00}, - 0x10, - {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a, - 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a, - 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10, - 0x04}, - {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04, - 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e, - 0x3e,0x2b,0x3b,0x2f}, - {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, - 0x3f} - }, -/* EGA_DAC */ - { - 0x00,0x10,0x04,0x0114, - {0x11,0x05,0x15,0x20}, - 0x30, - {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18, - 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38, - 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12, - 0x06}, - {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26, - 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e, - 0x1e,0x0b,0x1b,0x0f}, - {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, - 0x3f} - }, -/* VGA_DAC */ - { - 0x00,0x10,0x04,0x0114, - {0x11,0x09,0x15,0x2a}, - 0x3a, - {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05, - 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20, - 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10, - 0x1f}, - {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d, - 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15, - 0x1c,0x0e,0x11,0x15}, - {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00, - 0x04} - }, - { - 0x08,0x0c,0x10,0x0a08, - {0x0c,0x0e,0x10,0x0b}, - 0x0c, - {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00, - 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00, - 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00, - 0x06}, - {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08, - 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00, - 0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00} - }, -/* MD_D */ - { - 0x28,0x18,0x08,0x2000, - {0x09,0x0f,0x00,0x06}, - 0x63, - {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, - 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} - }, -/* MD_E */ - { - 0x50,0x18,0x08,0x4000, - {0x01,0x0f,0x00,0x06}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} - }, -/* ExtVGATable */ - { - 0x00,0x00,0x00,0x0000, - {0x01,0x0f,0x00,0x0e}, - 0x23, - {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x01,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, - 0xff} - }, -/* ROM_SAVEPTR */ - { - 0x9f,0x3b,0x00,0x00c0, - {0x00,0x00,0x00,0x00}, - 0x00, - {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f, - 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0, - 0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00} - }, -/* MD_F */ - { - 0x50,0x18,0x0e,0x8000, - {0x01,0x0f,0x00,0x06}, - 0xa2, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, - 0xff}, - {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00, - 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00, - 0x0b,0x00,0x05,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05, - 0xff} - }, -/* MD_10 */ - { - 0x50,0x18,0x0e,0x8000, - {0x01,0x0f,0x00,0x06}, - 0xa3, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} - }, -/* MD_0_350 */ - { - 0x28,0x18,0x0e,0x0800, - {0x09,0x03,0x00,0x02}, - 0xa3, - {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_1_350 */ - { - 0x28,0x18,0x0e,0x0800, - {0x09,0x03,0x00,0x02}, - 0xa3, - {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_2_350 */ - { - 0x50,0x18,0x0e,0x1000, - {0x01,0x03,0x00,0x02}, - 0xa3, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_3_350 */ - { - 0x50,0x18,0x0e,0x1000, - {0x01,0x03,0x00,0x02}, - 0xa3, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, - 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x08,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_0_1_400 */ - { - 0x28,0x18,0x10,0x0800, - {0x08,0x03,0x00,0x02}, - 0x67, - {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, - 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x0c,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_2_3_400 */ - { - 0x50,0x18,0x10,0x1000, - {0x00,0x03,0x00,0x02}, - 0x67, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x0c,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, - 0xff} - }, -/* MD_7_400 */ - { - 0x50,0x18,0x10,0x1000, - {0x00,0x03,0x00,0x02}, - 0x66, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, - 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, - 0x0e,0x00,0x0f,0x08}, - {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, - 0xff} - }, -/* MD_11 */ - { - 0x50,0x1d,0x10,0xa000, - {0x01,0x0f,0x00,0x06}, - 0xe3, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3, - 0xff}, - {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, - 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01, - 0xff} - }, -/* ExtEGATable */ - { - 0x50,0x1d,0x10,0xa000, - {0x01,0x0f,0x00,0x06}, - 0xe3, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, - 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, - 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x01,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, - 0xff} - }, -/* MD_13 */ - { - 0x28,0x18,0x08,0x2000, - {0x01,0x0f,0x00,0x0e}, - 0x63, - {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, - 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00, - 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3, - 0xff}, - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x41,0x00,0x0f,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, - 0xff} - } -}; - typedef struct _SiS310_ExtStruct { UCHAR Ext_ModeID; USHORT Ext_ModeFlag; USHORT Ext_ModeInfo; - USHORT Ext_Point; /* TW: Address of table entry in (older) BIOS image */ USHORT Ext_VESAID; - UCHAR Ext_VESAMEMSize; UCHAR Ext_RESINFO; UCHAR VB_ExtTVFlickerIndex; UCHAR VB_ExtTVEdgeIndex; @@ -506,103 +82,93 @@ typedef struct _SiS310_ExtStruct UCHAR REFindex; } SiS310_ExtStruct; -/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */ static const SiS310_ExtStruct SiS310_EModeIDTable[]= { - {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x? */ - {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x8 */ -/* {0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, */ /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */ - {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, /* 640x400x8 */ -/* {0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, */ /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */ - {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x8 */ -/* {0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, */ /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */ -/* {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, */ /* 720x480x8 */ - {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x8 BIOS (301/LVDS) */ - {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x8 */ - {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x16 */ - {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x16 */ - {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x32 */ - {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x32 */ - {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x? */ - {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x8 */ -/* {0x38,0x021b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, */ /* 1024x768x8 - 650/LVDS BIOS (no CRt2Mode) */ - {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */ -/* {0x3a,0x063b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, */ /* 1280x1024x8 - 650/LVDS BIOS*/ - {0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */ -/* {0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, */ /* 1600x1200x8 - 650/LVDS BIOS */ - {0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */ - {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25}, - {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25}, - {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08}, - {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x16 */ - {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00}, - {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x16 */ - {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13}, - {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x16 */ - {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a}, - {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */ - {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26}, -/* {0x50,0x921b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26}, */ /* 650/LVDS BIOS */ - {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27}, -/* {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, */ - {0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, /* 650/301 BIOS */ -/* {0x52,0xb21b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, */ /* 650/LVDS BIOS (no CRT2Mode) */ - {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26}, - {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27}, -/* {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28}, */ - {0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28}, /* BIOS (301+LVDS) */ - {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25}, -/* {0x59,0x921b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25}, */ /* 650/LVDS BIOS (no CRT2Mode) */ - {0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x8 fstn add new mode*/ - {0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x16 fstn add new mode*/ - {0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28}, /* TW: inserted 512x384x32 */ - {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10}, - {0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10}, /* TW: Inserted 640x400x32 */ - {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x32 */ - {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x32 */ - {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x32 */ - {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */ - {0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */ - {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */ - {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */ - {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */ - {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */ - {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */ - {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */ - {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x8 */ - {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x8 */ - {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x16 */ - {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x16 */ - {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x32 */ - {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x32 */ - {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x32 */ - {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x8 */ - {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x16 */ - {0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x8 - TW */ - {0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x16 - TW */ - {0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x32 - TW */ - /* TW: 650/LVDS BIOS new modes */ -/* {0x23,0x063b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, */ /* 1280x768x8 - 650/LVDS BIOS */ - {0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x8 */ - {0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x16 */ - {0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x32 */ - {0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */ -/* {0x26,0x063b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, */ /* 1400x1050x8 - 650/LVDS BIOS */ - {0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */ - {0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/ - {0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, /* TW: NEW 1152x864 - not in BIOS */ - {0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, - {0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, - {0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, /* TW: NEW 848x480 - not in BIOS */ - {0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, - {0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, - {0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, /* TW: NEW 856x480 - not in BIOS */ - {0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, - {0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, - {0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, /* TW: NEW 1360x768 - not in BIOS */ - {0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, - {0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, - {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00} + {0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x? */ + {0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x08}, /* 640x480x8 */ + {0x2f,0x0a1b,0x0305,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x10}, /* 640x400x8 */ + {0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x8 */ + {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x11}, /* 720x480x8 */ + {0x32,0x0a1b,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x12}, /* 720x576x8 */ + {0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x11}, /* 720x480x16 */ + {0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x12}, /* 720x576x16 */ + {0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x11}, /* 720x480x32 */ + {0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x12}, /* 720x576x32 */ + {0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x? */ + {0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x8 */ + {0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */ + {0x3c,0x0e3b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */ + {0x3d,0x0e7d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */ + {0x40,0x9a1c,0x0000,0x010d,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x15 */ + {0x41,0x9a1d,0x0000,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x16 */ + {0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480, 0x00,0x00,0x05,0x08}, + {0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x08}, /* 640x480x16 */ + {0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, + {0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x16 */ + {0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13}, + {0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x16 */ + {0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, + {0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */ + {0x50,0x9a1b,0x0001,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x26}, /* 320x240x8 */ + {0x51,0xba1b,0x0103,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x27}, /* 400x300x8 */ + {0x52,0xba1b,0x0204,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x28}, /* 512x384x8 */ + {0x56,0x9a1d,0x0001,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x26}, /* 320x240x16 */ + {0x57,0xba1d,0x0103,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x27}, /* 400x300x16 */ + {0x58,0xba1d,0x0204,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x28}, /* 512x384x16 */ + {0x59,0x9a1b,0x0000,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x8 */ + {0x5a,0x021b,0x0014,0x0138,SIS_RI_320x240, 0x00,0x00,0x04,0x3f}, /* 320x240x8 fstn */ + {0x5b,0x0a1d,0x0014,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x3f}, /* 320x240x16 fstn */ + {0x5c,0xba1f,0x0204,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x28}, /* 512x384x32 */ + {0x5d,0x0a1d,0x0305,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x10}, + {0x5e,0x0a1f,0x0305,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x10}, /* 640x400x32 */ + {0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x08}, /* 640x480x32 */ + {0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x00}, /* 800x600x32 */ + {0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x32 */ + {0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */ + {0x66,0x0eff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */ + {0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */ + {0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */ + {0x6b,0x07ff,0x080b,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */ + {0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */ + {0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */ + {0x6e,0x07ff,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */ + {0x70,0x2a1b,0x0410,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x34}, /* 800x480x8 */ + {0x71,0x0a1b,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x8 */ + {0x74,0x0a1d,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x16 */ + {0x75,0x0a3d,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x16 */ + {0x76,0x2a1f,0x0410,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x34}, /* 800x480x32 */ + {0x77,0x0a1f,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x32 */ + {0x78,0x0a3f,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x32 */ + {0x79,0x0a3b,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x8 */ + {0x7a,0x2a1d,0x0410,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x34}, /* 800x480x16 */ + {0x7c,0x0e3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x8 */ + {0x7d,0x0e7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x16 */ + {0x7e,0x0eff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x32 */ + {0x23,0x0e3b,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x8 */ + {0x24,0x0e7d,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x16 */ + {0x25,0x0eff,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x32 */ + {0x26,0x0e3b,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */ + {0x27,0x0e7d,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */ + {0x28,0x0eff,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/ + {0x29,0x0e1b,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, /* 1152x864 */ + {0x2a,0x0e3d,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, + {0x2b,0x0e7f,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, + {0x39,0x2a1b,0x0b17,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x45}, /* 848x480 */ + {0x3b,0x2a3d,0x0b17,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x45}, + {0x3e,0x2a7f,0x0b17,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x45}, + {0x3f,0x2a1b,0x0b13,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x47}, /* 856x480 */ + {0x42,0x2a3d,0x0b13,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x47}, + {0x45,0x2a7f,0x0b13,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x47}, + {0x48,0x2a1b,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, /* 1360x768 */ + {0x4b,0x2a3d,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, + {0x4e,0x2a7f,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, + {0x4f,0x9a1f,0x0000,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x25}, /* 320x200x32 */ + {0x53,0x9a1f,0x0001,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x26}, /* 320x240x32 */ + {0x54,0xba1f,0x0103,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x27}, /* 400x300x32 */ + {0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x4a}, /* 768x576x8 */ + {0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x4a}, /* 768x576x16 */ + {0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x4a}, /* 768x576x32 */ + {0xff,0x0000,0x0000,0x0000,0x00, 0x00,0x00,0x00,0x00} }; typedef struct _SiS310_Ext2Struct @@ -614,88 +180,86 @@ typedef struct _SiS310_Ext2Struct UCHAR ModeID; USHORT XRes; USHORT YRes; - USHORT ROM_OFFSET; } SiS310_Ext2Struct; static const SiS310_Ext2Struct SiS310_RefIndex[]= { -/* {0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, 0x0 - TW: Patch for Chrontel 7019 */ - {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */ - {0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */ - {0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */ - {0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */ - {0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */ - {0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */ - {0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */ - {0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */ -/* {0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, 0x8 - TW: Patch for Chrontel 7019 */ - {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */ - {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */ - {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */ - {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */ - {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */ - {0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */ - {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */ - {0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */ - {0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */ - {0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */ - {0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */ - {0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */ - {0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 301b TV1024x768*/ - {0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */ - {0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */ - {0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */ - {0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */ - {0x0047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */ - {0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */ - {0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */ - {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */ - {0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */ - {0x0007,0x20,0x21,0x00,0x3c,1600,1200,0x3af2}, /* 0x1e */ - {0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */ - {0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */ - {0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */ - {0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */ - {0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */ - {0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */ - {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */ - {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */ - {0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */ - {0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */ - {0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */ - {0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */ - {0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */ - {0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */ - {0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */ - {0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */ - {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */ - {0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */ - {0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */ - {0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */ - {0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */ - {0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */ - {0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */ - {0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */ - {0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */ - {0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */ - {0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */ - {0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */ - {0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */ - {0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */ - {0x0027,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */ - {0x0047,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */ - {0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */ /* FSTN mode */ - {0x0077,0x42,0x12,0x07,0x23,1280, 768,0x0000}, /* 0x40 */ /* TW: 650/LVDS/301LVx new mode */ - {0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */ /* TW: 650/LVDS/301LVx new mode */ - {0x0067,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */ /* TW: new, not in any BIOS */ - {0x0047,0x44,0x19,0x06,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */ - {0x0047,0x4a,0x1e,0x06,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */ - {0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */ - {0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz - Non-BIOS, new */ - {0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */ - {0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz - Non-BIOS, new */ - {0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */ - {0xffff,0x00,0x00,0x00,0x00, 0, 0,0x0000} + {0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 0x0 */ + {0x0467,0x0e,0x04,0x05,0x6a, 800, 600}, /* 0x1 */ + {0x0067,0x0f,0x08,0x48,0x6a, 800, 600}, /* 0x2 */ + {0x0067,0x10,0x07,0x8b,0x6a, 800, 600}, /* 0x3 */ + {0x0147,0x11,0x0a,0x00,0x6a, 800, 600}, /* 0x4 */ + {0x0147,0x12,0x0d,0x00,0x6a, 800, 600}, /* 0x5 - TW: Test sync change */ + {0x0047,0x13,0x13,0x00,0x6a, 800, 600}, /* 0x6 */ + {0x0047,0x14,0x1c,0x00,0x6a, 800, 600}, /* 0x7 */ + {0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 0x8 */ + {0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 0x9 */ + {0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0xa */ + {0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0xb */ + {0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0xc */ + {0xc047,0x0a,0x09,0x00,0x2e, 640, 480}, /* 0xd */ + {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480}, /* 0xe */ + {0xc047,0x0c,0x15,0x00,0x2e, 640, 480}, /* 0xf */ + {0x407f,0x04,0x00,0x00,0x2f, 640, 400}, /* 0x10 */ + {0xc00f,0x3c,0x01,0x06,0x31, 720, 480}, /* 0x11 */ + {0x000f,0x3d,0x03,0x06,0x32, 720, 576}, /* 0x12 */ + {0x0187,0x15,0x06,0x00,0x37,1024, 768}, /* 0x13 */ + {0xc877,0x16,0x0b,0x06,0x37,1024, 768}, /* 0x14 */ + {0xc067,0x17,0x0f,0x49,0x37,1024, 768}, /* 0x15 */ + {0x0267,0x18,0x11,0x00,0x37,1024, 768}, /* 0x16 */ + {0x0047,0x19,0x16,0x8c,0x37,1024, 768}, /* 0x17 */ + {0x0047,0x1a,0x1b,0x00,0x37,1024, 768}, /* 0x18 */ + {0x0007,0x1b,0x1f,0x00,0x37,1024, 768}, /* 0x19 */ + {0x0387,0x1c,0x11,0x00,0x3a,1280,1024}, /* 0x1a */ + {0x0077,0x1d,0x19,0x07,0x3a,1280,1024}, /* 0x1b */ + {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024}, /* 0x1c */ + {0x0007,0x1f,0x20,0x00,0x3a,1280,1024}, /* 0x1d */ + {0x0867,0x20,0x21,0x09,0x3c,1600,1200}, /* 0x1e */ + {0x0007,0x21,0x22,0x00,0x3c,1600,1200}, /* 0x1f */ + {0x0007,0x22,0x23,0x00,0x3c,1600,1200}, /* 0x20 */ + {0x0007,0x23,0x25,0x00,0x3c,1600,1200}, /* 0x21 */ + {0x0007,0x24,0x26,0x00,0x3c,1600,1200}, /* 0x22 */ + {0x0007,0x25,0x2c,0x00,0x3c,1600,1200}, /* 0x23 */ + {0x0007,0x26,0x34,0x00,0x3c,1600,1200}, /* 0x24 */ + {0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 0x25 */ + {0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 0x26 */ + {0x007f,0x02,0x04,0x05,0x51, 400, 300}, /* 0x27 */ + {0xc077,0x03,0x0b,0x06,0x52, 512, 384}, /* 0x28 */ + {0x8007,0x27,0x27,0x00,0x68,1920,1440}, /* 0x29 */ + {0x4007,0x28,0x29,0x00,0x68,1920,1440}, /* 0x2a */ + {0x4007,0x29,0x2e,0x00,0x68,1920,1440}, /* 0x2b */ + {0x4007,0x2a,0x30,0x00,0x68,1920,1440}, /* 0x2c */ + {0x4007,0x2b,0x35,0x00,0x68,1920,1440}, /* 0x2d */ + {0x4005,0x2c,0x39,0x00,0x68,1920,1440}, /* 0x2e */ + {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536}, /* 0x2f */ + {0x4007,0x2e,0x31,0x00,0x6c,2048,1536}, /* 0x30 */ + {0x4007,0x2f,0x33,0x00,0x6c,2048,1536}, /* 0x31 */ + {0x4007,0x30,0x37,0x00,0x6c,2048,1536}, /* 0x32 */ + {0x4005,0x31,0x38,0x00,0x6c,2048,1536}, /* 0x33 */ + {0x0057,0x32,0x40,0x08,0x70, 800, 480}, /* 0x34 */ + {0x0047,0x33,0x07,0x08,0x70, 800, 480}, /* 0x35 */ + {0x0047,0x34,0x0a,0x08,0x70, 800, 480}, /* 0x36 */ + {0x0057,0x35,0x0b,0x09,0x71,1024, 576}, /* 0x37 */ + {0x0047,0x36,0x11,0x09,0x71,1024, 576}, /* 0x38 */ + {0x0047,0x37,0x16,0x09,0x71,1024, 576}, /* 0x39 */ + {0x0057,0x38,0x19,0x0a,0x75,1280, 720}, /* 0x3a */ + {0x0047,0x39,0x1e,0x0a,0x75,1280, 720}, /* 0x3b */ + {0x0007,0x3a,0x20,0x0a,0x75,1280, 720}, /* 0x3c */ + {0x0067,0x3b,0x19,0x08,0x7c,1280, 960}, /* 0x3d */ + {0x0027,0x4c,0x59,0x08,0x7c,1280, 960}, /* 0x3e */ + {0xc07f,0x4e,0x00,0x06,0x5a, 320, 240}, /* 0x3f */ /* FSTN 320x240 */ + {0x0077,0x42,0x5b,0x08,0x23,1280, 768}, /* 0x40 */ /* TW: 0x5b was 0x12 */ + {0x0067,0x43,0x4d,0x08,0x26,1400,1050}, /* 0x41 */ + {0x0007,0x4b,0x5a,0x08,0x26,1400,1050}, /* 0x42 TW: not in any BIOS */ + {0x0047,0x44,0x19,0x00,0x29,1152, 864}, /* 0x43 TW: Non-BIOS, new */ + {0x0047,0x4a,0x1e,0x00,0x29,1152, 864}, /* 0x44 TW: Non-BIOS, new */ + {0x00c7,0x45,0x57,0x00,0x39, 848, 480}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */ + {0xc067,0x46,0x55,0x0b,0x39, 848, 480}, /* 0x46 TW: 848x480-60Hz - Non-BIOS, new */ + {0x00c7,0x47,0x57,0x00,0x3f, 856, 480}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */ + {0xc047,0x48,0x57,0x00,0x3f, 856, 480}, /* 0x48 TW: 856x480-60Hz - Non-BIOS, new */ + {0x0067,0x49,0x58,0x0c,0x48,1360, 768}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */ + {0x000f,0x4d,0x03,0x06,0x5f, 768, 576}, /* 0x4a TW: 768x576 */ + {0xffff,0x00,0x00,0x00,0x00, 0, 0} }; typedef struct _SiS310_CRT1TableStruct @@ -720,7 +284,7 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]= {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05, 0x00}}, /* 0x4 */ -#if 0 +#if 0 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, 0x00}}, /* 0x5 */ @@ -930,11 +494,6 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]= {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, 0x00}}, /* 0x45 */ -#if 0 - {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */ - 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, - 0x00}}, /* 0x46 */ -#endif {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */ 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06, 0x00}}, /* 0x46 */ @@ -955,19 +514,25 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]= 0x00}}, /* 0x4b */ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07, - 0x01}} /* 0x4c */ + 0x01}}, /* 0x4c */ + {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */ + 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, + 0x01}}, /* 0x4d */ + {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */ + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, + 0x00}} /* 0x4e */ }; - typedef struct _SiS310_MCLKDataStruct { UCHAR SR28,SR29,SR2A; USHORT CLOCK; } SiS310_MCLKDataStruct; +#ifdef LINUXBIOS static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] = { - { 0x3b,0x22,0x01,143}, /* TW: Was { 0x5c,0x23,0x01,166}, */ + { 0x3b,0x22,0x01,143}, { 0x5c,0x23,0x01,166}, { 0x5c,0x23,0x01,166}, { 0x5c,0x23,0x01,166}, @@ -977,7 +542,7 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] = { 0x5c,0x23,0x01,166} }; -static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] = /* @ 0x54 */ +static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] = { { 0x5a,0x64,0x82, 66}, { 0xb3,0x45,0x82, 83}, @@ -988,8 +553,22 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] = /* @ 0x54 */ { 0x37,0x22,0x82,133}, { 0x37,0x22,0x82,133} }; +#endif + +static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] = +{ + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x7c,0x08,0x01,200}, + { 0x79,0x06,0x01,250}, + { 0x7c,0x08,0x01,200}, + { 0x7c,0x08,0x01,200}, + { 0x7c,0x08,0x01,200}, + { 0x79,0x06,0x01,250} +}; -static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] = /* @ 0x54 */ +#ifdef LINUXBIOS +static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] = /* TODO */ { { 0x5c,0x23,0x01,166}, { 0x5c,0x23,0x01,166}, @@ -1000,8 +579,9 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] = /* @ 0x54 */ { 0x7c,0x08,0x01,200}, { 0x79,0x06,0x01,250} }; +#endif -static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] = /* @ 0x155 */ +static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] = { { 0x29,0x21,0x82,150}, { 0x5c,0x23,0x82,166}, @@ -1013,6 +593,7 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] = /* @ 0x155 */ { 0x37,0x22,0x82,133} }; +#ifdef LINUXBIOS typedef struct _SiS310_ECLKDataStruct { UCHAR SR2E,SR2F,SR30; @@ -1026,6 +607,7 @@ static const SiS310_ECLKDataStruct SiS310_ECLKData[]= { 0x5c,0x23,0x01,166}, { 0x5c,0x23,0x01,166} }; +#endif typedef struct _SiS310_VCLKDataStruct { @@ -1035,22 +617,22 @@ typedef struct _SiS310_VCLKDataStruct static const SiS310_VCLKDataStruct SiS310_VCLKData[]= { - { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x5647 */ - { 0x4e,0xe4, 28}, /* 0x1 */ - { 0x57,0xe4, 31}, /* 0x2 */ - { 0xc3,0xc8, 36}, /* 0x3 */ - { 0x42,0xe2, 40}, /* 0x4 */ - { 0xfe,0xcd, 43}, /* 0x5 */ - { 0x5d,0xc4, 44}, /* 0x6 */ - { 0x52,0xe2, 49}, /* 0x7 */ - { 0x53,0xe2, 50}, /* 0x8 */ - { 0x74,0x67, 52}, /* 0x9 */ - { 0x6d,0x66, 56}, /* 0xa */ - { 0x5a,0x64, 65}, /* 0xb */ /* TW: was 6c c3 - WRONG */ - { 0x46,0x44, 67}, /* 0xc */ - { 0xb1,0x46, 68}, /* 0xd */ - { 0xd3,0x4a, 72}, /* 0xe */ - { 0x29,0x61, 75}, /* 0xf */ + { 0x1b,0xe1, 25}, /* 0x00 */ + { 0x4e,0xe4, 28}, /* 0x01 */ + { 0x57,0xe4, 31}, /* 0x02 */ + { 0xc3,0xc8, 36}, /* 0x03 */ + { 0x42,0xe2, 40}, /* 0x04 */ + { 0xfe,0xcd, 43}, /* 0x05 */ + { 0x5d,0xc4, 44}, /* 0x06 */ + { 0x52,0xe2, 49}, /* 0x07 */ + { 0x53,0xe2, 50}, /* 0x08 */ + { 0x74,0x67, 52}, /* 0x09 */ + { 0x6d,0x66, 56}, /* 0x0a */ + { 0x5a,0x64, 65}, /* 0x0b */ /* TW: was 6c c3 - WRONG */ + { 0x46,0x44, 67}, /* 0x0c */ + { 0xb1,0x46, 68}, /* 0x0d */ + { 0xd3,0x4a, 72}, /* 0x0e */ + { 0x29,0x61, 75}, /* 0x0f */ { 0x6e,0x46, 76}, /* 0x10 */ { 0x2b,0x61, 78}, /* 0x11 */ { 0x31,0x42, 79}, /* 0x12 */ @@ -1060,7 +642,7 @@ static const SiS310_VCLKDataStruct SiS310_VCLKData[]= { 0x62,0x44, 94}, /* 0x16 */ { 0x2b,0x41,104}, /* 0x17 */ { 0x3a,0x23,105}, /* 0x18 */ - { 0x70,0x44,108}, /* 0x19 */ + { 0x70,0x44,108}, /* 0x19 */ /* 1400x1050 LCD */ { 0x3c,0x23,109}, /* 0x1a */ { 0x5e,0x43,113}, /* 0x1b */ { 0xbc,0x44,116}, /* 0x1c */ @@ -1093,14 +675,13 @@ static const SiS310_VCLKDataStruct SiS310_VCLKData[]= { 0xea,0x08,340}, /* 0x37 */ { 0xe8,0x07,376}, /* 0x38 */ { 0xde,0x06,389}, /* 0x39 */ - { 0x52,0x2a, 54}, /* 0x3a */ - { 0x52,0x6a, 27}, /* 0x3b */ - { 0x62,0x24, 70}, /* 0x3c */ - { 0x62,0x64, 70}, /* 0x3d */ - { 0xa8,0x4c, 30}, /* 0x3e */ - { 0x20,0x26, 33}, /* 0x3f */ + { 0x52,0x2a, 54}, /* 0x3a */ /* 301 TV */ + { 0x52,0x6a, 27}, /* 0x3b */ /* 301 TV */ + { 0x62,0x24, 70}, /* 0x3c */ /* 301 TV */ + { 0x62,0x64, 70}, /* 0x3d */ /* 301 TV */ + { 0xa8,0x4c, 30}, /* 0x3e */ /* 301 TV */ + { 0x20,0x26, 33}, /* 0x3f */ /* 301 TV */ { 0x31,0xc2, 39}, /* 0x40 */ - /* TW: 650/LVDS BIOS @ 0x574b new: */ { 0x60,0x36, 30}, /* 0x41 */ /* Chrontel */ { 0x40,0x4a, 28}, /* 0x42 */ /* Chrontel */ { 0x9f,0x46, 44}, /* 0x43 */ /* Chrontel */ @@ -1112,7 +693,7 @@ static const SiS310_VCLKDataStruct SiS310_VCLKData[]= { 0xce,0x3c, 39}, /* 0x49 */ { 0x52,0x4a, 36}, /* 0x4a */ /* Chrontel */ { 0x34,0x61, 95}, /* 0x4b */ - { 0x78,0x27,108}, /* 0x4c - was 102 */ /* TW: Last entry in 650/301 BIOS */ + { 0x78,0x27,108}, /* 0x4c - was 102 */ { 0x66,0x43,123}, /* 0x4d */ /* Modes 0x26-0x28 (1400x1050) */ { 0x41,0x4e, 21}, /* 0x4e */ { 0xa1,0x4a, 29}, /* 0x4f */ /* Chrontel */ @@ -1124,9 +705,10 @@ static const SiS310_VCLKDataStruct SiS310_VCLKData[]= { 0x62,0xc6, 34}, /* 0x55 - added for 848x480-60 (not in any BIOS) */ { 0x6a,0xc6, 37}, /* 0x56 - added for 848x480-75 (not in any BIOS) - TEMP */ { 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */ - { 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) - TEMP */ + { 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */ { 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */ - { 0x56,0x07,156} /* 0x5a - added for 1400x1050-75 */ + { 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */ + { 0x70,0x29, 81} /* 0x5b */ /* 1280x768 LCD */ }; typedef struct _SiS310_VBVCLKDataStruct @@ -1137,22 +719,22 @@ typedef struct _SiS310_VBVCLKDataStruct static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]= { - { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x579c */ - { 0x4e,0xe4, 28}, /* 0x1 */ - { 0x57,0xe4, 31}, /* 0x2 */ - { 0xc3,0xc8, 36}, /* 0x3 */ - { 0x42,0x47, 40}, /* 0x4 */ - { 0xfe,0xcd, 43}, /* 0x5 */ - { 0x5d,0xc4, 44}, /* 0x6 */ - { 0x52,0x47, 49}, /* 0x7 */ - { 0x53,0x47, 50}, /* 0x8 */ - { 0x74,0x67, 52}, /* 0x9 */ - { 0x6d,0x66, 56}, /* 0xa */ - { 0x35,0x62, 65}, /* 0xb */ /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62 */ - { 0x46,0x44, 67}, /* 0xc */ - { 0xb1,0x46, 68}, /* 0xd */ - { 0xd3,0x4a, 72}, /* 0xe */ - { 0x29,0x61, 75}, /* 0xf */ + { 0x1b,0xe1, 25}, /* 0x00 */ + { 0x4e,0xe4, 28}, /* 0x01 */ + { 0x57,0xe4, 31}, /* 0x02 */ + { 0xc3,0xc8, 36}, /* 0x03 */ + { 0x42,0x47, 40}, /* 0x04 */ + { 0xfe,0xcd, 43}, /* 0x05 */ + { 0x5d,0xc4, 44}, /* 0x06 */ + { 0x52,0x47, 49}, /* 0x07 */ + { 0x53,0x47, 50}, /* 0x08 */ + { 0x74,0x67, 52}, /* 0x09 */ + { 0x6d,0x66, 56}, /* 0x0a */ + { 0x35,0x62, 65}, /* 0x0b */ /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62 */ + { 0x46,0x44, 67}, /* 0x0c */ + { 0xb1,0x46, 68}, /* 0x0d */ + { 0xd3,0x4a, 72}, /* 0x0e */ + { 0x29,0x61, 75}, /* 0x0f */ { 0x6d,0x46, 75}, /* 0x10 */ { 0x41,0x43, 78}, /* 0x11 */ { 0x31,0x42, 79}, /* 0x12 */ @@ -1162,7 +744,7 @@ static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]= { 0x62,0x44, 94}, /* 0x16 */ { 0x2b,0x22,104}, /* 0x17 */ { 0x49,0x24,105}, /* 0x18 */ - { 0xf8,0x2f,108}, /* 0x19 */ + { 0xf8,0x2f,108}, /* 0x19 */ /* 1400x1050 LCD */ { 0x3c,0x23,109}, /* 0x1a */ { 0x5e,0x43,113}, /* 0x1b */ { 0xbc,0x44,116}, /* 0x1c */ @@ -1195,86 +777,48 @@ static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]= { 0xea,0x08,340}, /* 0x37 */ { 0xe8,0x07,376}, /* 0x38 */ { 0xde,0x06,389}, /* 0x39 */ - { 0x52,0x2a, 54}, /* 0x3a */ - { 0x52,0x6a, 27}, /* 0x3b */ - { 0x62,0x24, 70}, /* 0x3c */ - { 0x62,0x64, 70}, /* 0x3d */ - { 0xa8,0x4c, 30}, /* 0x3e */ - { 0x20,0x26, 33}, /* 0x3f */ + { 0x52,0x2a, 54}, /* 0x3a */ /* 301 TV */ + { 0x52,0x6a, 27}, /* 0x3b */ /* 301 TV */ + { 0x62,0x24, 70}, /* 0x3c */ /* 301 TV */ + { 0x62,0x64, 70}, /* 0x3d */ /* 301 TV */ + { 0xa8,0x4c, 30}, /* 0x3e */ /* 301 TV */ + { 0x20,0x26, 33}, /* 0x3f */ /* 301 TV */ { 0x31,0xc2, 39}, /* 0x40 */ - /* TW: 650/LVDS+301 BIOS (@ 0x58a0 in LVDS) new: */ - { 0x2e,0x48, 25}, /* 0x41 */ - { 0x24,0x46, 25}, /* 0x42 */ - { 0x26,0x64, 28}, /* 0x43 */ - { 0x37,0x64, 40}, /* 0x44 */ - { 0xa1,0x42,108}, /* 0x45 */ - { 0x37,0x61,100}, /* 0x46 */ - { 0x78,0x27,108} /* 0x47 */ - /* --- 0x58bc --- */ + { 0x2e,0x48, 25}, /* 0x41 */ /* Replacement for LCD on 315 for index 0 */ + { 0x24,0x46, 25}, /* 0x42 */ /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */ + { 0x26,0x64, 28}, /* 0x43 */ /* Replacement for LCD on 315 for index 1 */ + { 0x37,0x64, 40}, /* 0x44 */ /* Replacement for LCD on 315 for index 4 */ + { 0xa1,0x42,108}, /* 0x45 */ /* 1280x960 LCD */ + { 0x37,0x61,100}, /* 0x46 */ /* 1280x960 LCD */ + { 0x78,0x27,108}, /* 0x47 */ + { 0x97,0x2c, 26}, /* 0x48 */ /* UNUSED - Entries from here new, not in any BIOS */ + { 0xce,0x3c, 39}, /* 0x49 */ /* UNUSED */ + { 0x52,0x4a, 36}, /* 0x4a */ /* UNUSED */ + { 0x34,0x61, 95}, /* 0x4b */ /* UNUSED */ + { 0x78,0x27,108}, /* 0x4c */ /* UNUSED */ + { 0x66,0x43,123}, /* 0x4d */ /* 1400x1050-60 */ + { 0x41,0x4e, 21}, /* 0x4e */ /* UNUSED */ + { 0xa1,0x4a, 29}, /* 0x4f */ /* UNUSED */ + { 0x19,0x42, 42}, /* 0x50 */ /* UNUSED */ + { 0x54,0x46, 58}, /* 0x51 */ /* UNUSED */ + { 0x25,0x42, 61}, /* 0x52 */ /* UNUSED */ + { 0x44,0x44, 66}, /* 0x53 */ /* UNUSED */ + { 0x3a,0x62, 70}, /* 0x54 */ /* UNUSED */ + { 0x62,0xc6, 34}, /* 0x55 */ /* 848x480-60 */ + { 0x6a,0xc6, 37}, /* 0x56 */ /* 848x480-75 - TEMP, UNUSED */ + { 0xbf,0xc8, 35}, /* 0x57 */ /* 856x480-38i,60 */ + { 0x30,0x23, 88}, /* 0x58 */ /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */ + { 0x52,0x07,149}, /* 0x59 */ /* 1280x960-85 - UNUSED */ + { 0x56,0x07,156}, /* 0x5a */ /* 1400x1050-75 - UNUSED */ + { 0x70,0x29, 81} /* 0x5b */ /* 1280x768 LCD */ }; static const UCHAR SiS310_ScreenOffset[] = { 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64, - 0x78,0x80,0x2d,0x35,0x57,0x48,0x55, + 0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30, 0xff -}; /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */ - -typedef struct _SiS310_StResInfoStruct -{ - USHORT HTotal; - USHORT VTotal; -} SiS310_StResInfoStruct; - -static const SiS310_StResInfoStruct SiS310_StResInfo[]= -{ - { 640,400}, - { 640,350}, - { 720,400}, - { 720,350}, - { 640,480} -}; - -typedef struct _SiS310_ModeResInfoStruct -{ - USHORT HTotal; - USHORT VTotal; - UCHAR XChar; - UCHAR YChar; -} SiS310_ModeResInfoStruct; - -static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] = -{ - { 320, 200, 8, 8}, /* 0x00 */ - { 320, 240, 8, 8}, /* 0x01 */ - { 320, 400, 8, 8}, /* 0x02 */ - { 400, 300, 8, 8}, /* 0x03 */ - { 512, 384, 8, 8}, /* 0x04 */ - { 640, 400, 8,16}, /* 0x05 */ - { 640, 480, 8,16}, /* 0x06 */ - { 800, 600, 8,16}, /* 0x07 */ - { 1024, 768, 8,16}, /* 0x08 */ - { 1280,1024, 8,16}, /* 0x09 */ - { 1600,1200, 8,16}, /* 0x0a */ - { 1920,1440, 8,16}, /* 0x0b */ - { 2048,1536, 8,16}, /* 0x0c */ - { 720, 480, 8,16}, /* 0x0d */ - { 720, 576, 8,16}, /* 0x0e */ - { 1280, 960, 8,16}, /* 0x0f */ - { 800, 480, 8,16}, /* 0x10 */ - { 1024, 576, 8,16}, /* 0x11 */ - { 1280, 720, 8,16}, /* 0x12 */ - { 856, 480, 8,16}, /* 0x13 - TW: New, not in any BIOS */ - { 1280, 768, 8,16}, /* 0x14 20; TW: New */ - { 1400,1050, 8,16}, /* 0x15 21; TW: New */ - { 1152, 864, 8,16}, /* 0x16 - TW: New, not in any BIOS */ - { 848, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */ - { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */ -}; - -static const UCHAR SiS310_OutputSelect = 0x40; - -static const UCHAR SiS310_SoftSetting = 0x30; /* TW: RAM setting */ +}; static const UCHAR SiS310_SR15[8][4]={ {0x00,0x04,0x60,0x60}, @@ -1316,21 +860,11 @@ static UCHAR SiS310_CRT2Data_4_10 = 0x80; static const USHORT SiS310_RGBSenseData = 0xd1; static const USHORT SiS310_VideoSenseData = 0xb9; static const USHORT SiS310_YCSenseData = 0xb3; -static const USHORT SiS310_RGBSenseData2 = 0x0190; /*301b*/ +static const USHORT SiS310_RGBSenseData2 = 0x0190; static const USHORT SiS310_VideoSenseData2 = 0x0174; static const USHORT SiS310_YCSenseData2 = 0x016b; #endif -static const UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */ -static const UCHAR SiS310_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */ -static const UCHAR SiS310_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* TW: palm*/ -static const UCHAR SiS310_PALNPhase[] = {0x21,0xF4,0x3E,0xBA}; /* TW: paln*/ -static const UCHAR SiS310_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6}; -static const UCHAR SiS310_PALPhase2[] = {0x2a,0x09,0x86,0xe9}; -static const UCHAR SiS310_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/ -static const UCHAR SiS310_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/ -static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a}; - typedef struct _SiS310_LCDDataStruct { USHORT RVBHCMAX; @@ -1352,12 +886,12 @@ static const SiS310_LCDDataStruct SiS310_StLCD1024x768Data[]= { 1, 1,1344, 806,1344, 806} }; -static const SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] = /* TW: Checked */ +static const SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] = { - { 12, 5, 896, 512,1344, 806}, - { 12, 5, 896, 510,1344, 806}, - { 32, 15,1008, 505,1344, 806}, - { 32, 15,1008, 514,1344, 806}, + { 42, 25,1536, 419,1344, 806}, + { 48, 25,1536, 369,1344, 806}, + { 42, 25,1536, 419,1344, 806}, + { 48, 25,1536, 369,1344, 806}, { 12, 5, 896, 500,1344, 806}, { 42, 25,1024, 625,1344, 806}, { 1, 1,1344, 806,1344, 806}, @@ -1367,14 +901,14 @@ static const SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] = /* TW: Checke { 12, 5, 896, 500,1344, 806}, { 42, 25,1024, 625,1344, 806}, { 1, 1,1344, 806,1344, 806} + }; -static const SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = /* TW: Checked */ +static const SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = { { 62, 25, 800, 546,1344, 806}, { 32, 15, 930, 546,1344, 806}, -/* { 32, 15, 930, 546,1344, 806}, */ - { 62, 25, 800, 546,1344, 806}, /* TW: Different in 650/301LV BIOS */ + { 62, 25, 800, 546,1344, 806}, { 104, 45, 945, 496,1344, 806}, { 62, 25, 800, 546,1344, 806}, { 31, 18,1008, 624,1344, 806}, @@ -1393,7 +927,7 @@ static const SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] = { 1, 1,1688,1066,1688,1066} }; -static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = /* TW: Checked */ +static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = { { 211, 60,1024, 501,1688,1066}, { 211, 60,1024, 508,1688,1066}, @@ -1402,7 +936,8 @@ static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = /* TW: Checke { 211, 60,1024, 500,1688,1066}, { 211, 75,1024, 625,1688,1066}, { 211, 120,1280, 798,1688,1066}, - { 1, 1,1688,1066,1688,1066} + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1800,1000,1688,1066} /* 1280x960 - does not work, use panel scaler instead */ }; static const SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] = @@ -1417,19 +952,19 @@ static const SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] = { 1, 1,1688,1066,1688,1066} }; -static const SiS310_LCDDataStruct SiS310_NoScaleData1024x768[] = /* TW: Checked */ +static const SiS310_LCDDataStruct SiS310_NoScaleData1024x768[] = { { 1, 1,1344, 806,1344, 806}, { 1, 1,1344, 806,1344, 806}, { 1, 1,1344, 806,1344, 806}, - { 1, 1,1344, 806,1344, 806}, - { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806}, /* 640x400 - does not work */ + { 1, 1,1344, 806,1344, 806}, /* 640x480 - does not work */ { 1, 1,1344, 806,1344, 806}, { 1, 1,1344, 806,1344, 806}, { 1, 1,1344, 806,1344, 806} }; -static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] = /* TW: New; Checked */ +static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] = { { 1, 1,1688,1066,1688,1066}, { 1, 1,1688,1066,1688,1066}, @@ -1438,261 +973,19 @@ static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] = /* TW: New; { 1, 1,1688,1066,1688,1066}, { 1, 1,1688,1066,1688,1066}, { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066}, { 1, 1,1688,1066,1688,1066} }; -static const SiS310_LCDDataStruct SiS310_LCD1280x960Data[] = -{ - { 9, 2, 800, 500,1800,1000}, - { 9, 2, 800, 500,1800,1000}, - { 4, 1, 900, 500,1800,1000}, - { 4, 1, 900, 500,1800,1000}, - { 9, 2, 800, 500,1800,1000}, - { 30, 11,1056, 625,1800,1000}, - { 5, 3,1350, 800,1800,1000}, - { 1, 1,1576,1050,1576,1050}, - { 1, 1,1800,1000,1800,1000} -}; - -static const SiS310_LCDDataStruct SiS310_StLCD1400x1050Data[] = /* TW: New */ -{ /* TW: New from 1.11.6s */ - { 211, 100, 2100, 408, 1688, 1066 }, - { 211, 64, 1536, 358, 1688, 1066 }, - { 211, 100, 2100, 408, 1688, 1066 }, - { 211, 64, 1536, 358, 1688, 1066 }, - { 211, 48, 840, 488, 1688, 1066 }, - { 211, 72, 1008, 609, 1688, 1066 }, - { 211, 128, 1400, 776, 1688, 1066 }, - { 211, 205, 1680, 1041, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 } -}; - -static const SiS310_LCDDataStruct SiS310_ExtLCD1400x1050Data[] = /* TW: New */ -{ /* TW: New from 1.11.6s */ - { 211, 100, 2100, 408, 1688, 1066 }, - { 211, 64, 1536, 358, 1688, 1066 }, - { 211, 100, 2100, 408, 1688, 1066 }, - { 211, 64, 1536, 358, 1688, 1066 }, - { 211, 48, 840, 488, 1688, 1066 }, - { 211, 72, 1008, 609, 1688, 1066 }, - { 211, 128, 1400, 776, 1688, 1066 }, - { 211, 205, 1680, 1041, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 } -}; - -static const SiS310_LCDDataStruct SiS310_NoScaleData1400x1050[] = /* TW: New */ -{ /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */ - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 }, - { 1, 1, 1688, 1066, 1688, 1066 } -}; - -static const SiS310_LCDDataStruct SiS310_StLCD1600x1200Data[] = /* TW: New */ -{ /* TODO */ - { 0, 0, 0, 0, 0, 0} -}; - -static const SiS310_LCDDataStruct SiS310_ExtLCD1600x1200Data[] = /* TW: New */ -{ /* TODO */ - { 0, 0, 0, 0, 0, 0} -}; - -static const SiS310_LCDDataStruct SiS310_NoScaleData1600x1200[] = /* TW: New */ -{ /* TODO */ - { 0, 0, 0, 0, 0, 0} -}; - -typedef struct _SiS310_TVDataStruct -{ - USHORT RVBHCMAX; - USHORT RVBHCFACT; - USHORT VGAHT; - USHORT VGAVT; - USHORT TVHDE; - USHORT TVVDE; - USHORT RVBHRS; - UCHAR FlickerMode; - USHORT HALFRVBHRS; - UCHAR RY1COE; - UCHAR RY2COE; - UCHAR RY3COE; - UCHAR RY4COE; -} SiS310_TVDataStruct; - -static const SiS310_TVDataStruct SiS310_StPALData[]= -{ - { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22}, - { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22}, - { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, - { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, - { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22}, - { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22} -}; - -static const SiS310_TVDataStruct SiS310_ExtPALData[] = /* TW: Verfied (1.10.7w) */ -{ - { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, - { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, - { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18}, - { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a}, - { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480 */ - { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600 */ - { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x480/576 */ - { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} /* 1024x768 */ -}; - -static const SiS310_TVDataStruct SiS310_StNTSCData[]= -{ - { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18}, - { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18}, - { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, - { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, - { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18} -}; - -static const SiS310_TVDataStruct SiS310_ExtNTSCData[]= -{ - { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, - { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, - { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18}, - { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a}, - { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480 */ - { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600 */ - { 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480/576 */ - { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} /* 1024x768 */ -}; - -/* TW: These tables will need data ! */ -static const SiS310_TVDataStruct SiS310_St1HiTVData[]= -{ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} -}; - -static const SiS310_TVDataStruct SiS310_St2HiTVData[]= -{ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} -}; - -static const SiS310_TVDataStruct SiS310_ExtHiTVData[]= -{ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} -}; - -static const UCHAR SiS310_NTSCTiming[] = { /* TW: New (checked 1.09, 1.10.6s) */ - 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, - 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, - 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b, - 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, - 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, - 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50, - 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 -}; - -static const UCHAR SiS310_PALTiming[] = { /* TW: New (checked 1.09, 1.10.6s) */ - 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70, - 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b, - 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17, - 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02, - 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63, - 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00 -}; - -#ifdef oldHV -static const UCHAR SiS310_HiTVExtTiming[] = { /* TW: New */ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, - 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, - 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, - 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 -}; - -static const UCHAR SiS310_HiTVSt1Timing[] = { /* TW: New */ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03, - 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10, - 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86, - 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00 -}; - -static const UCHAR SiS310_HiTVSt2Timing[] = { /* TW: New */ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, - 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, - 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, - 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 -}; - -static const UCHAR SiS310_HiTVTextTiming[] = { /* TW: New */ - 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, - 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, - 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, - 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03, - 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20, - 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40, - 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96, - 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00 -}; - -static const UCHAR SiS310_HiTVGroup3Data[] = { /* TW: New */ - 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f, - 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6, - 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, - 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44, - 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, - 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9, - 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75, - 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 -}; - -static const UCHAR SiS310_HiTVGroup3Simu[] = { /* TW: New */ - 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95, - 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6, - 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, - 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11, - 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, - 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4, - 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, - 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 -}; - -static const UCHAR SiS310_HiTVGroup3Text[] = { /* TW: New */ - 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7, - 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6, - 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, - 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22, - 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, - 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca, - 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, - 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 -}; -#endif typedef struct _SiS310_PanelDelayTblStruct { UCHAR timer[2]; } SiS310_PanelDelayTblStruct; -static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]= /* TW: New */ +static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]= { - {{0x10,0x40}}, /* TW: from 650/301LVx 1.10.6s BIOS */ + {{0x10,0x40}}, {{0x10,0x40}}, {{0x10,0x40}}, {{0x10,0x40}}, @@ -1708,24 +1001,6 @@ static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]= /* TW: New */ {{0x10,0x40}}, {{0x10,0x40}}, {{0x10,0x40}} -#if 0 - {{0x28,0xc8}}, /* TW: from 650/301LV BIOS */ - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}}, - {{0x28,0xc8}} -#endif }; static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]= @@ -1756,335 +1031,7 @@ typedef struct _SiS310_LVDSDataStruct USHORT LCDVT; } SiS310_LVDSDataStruct; -static const SiS310_LVDSDataStruct SiS310_LVDS320x480Data_1[]= -{ - {848, 433,400, 525}, - {848, 389,400, 525}, - {848, 433,400, 525}, - {848, 389,400, 525}, - {848, 518,400, 525}, - {1056,628,400, 525}, - {400, 525,400, 525}, - {800, 449,1000, 644}, - {800, 525,1000, 635} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_1[]= /* TW: New */ -{ - {848, 433,1060, 629}, - {848, 389,1060, 629}, - {848, 433,1060, 629}, - {848, 389,1060, 629}, - {848, 518,1060, 629}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {800, 449,1000, 644}, - {800, 525,1000, 635} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_2[]= /* TW: New */ -{ - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {800, 449,1000, 644}, - {800, 525,1000, 635} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_1[]= /* TW: New */ -{ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, /* 640x480 */ - {1050, 638,1344, 806}, /* 800x600 */ - {1344, 806,1344, 806}, /* 1024x768 */ - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_2[]= /* TW: New */ -{ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_1[]= /* TW: New - TODO */ -{ /* TW: Temp data, invalid (is identical to 1024x768) */ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_2[]= /* TW: New - TODO */ -{ /* TW: Temp data, invalid (is identical to 1024x768) */ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_1[]= /* TW: New */ -{ - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 496, 1688, 1066}, - {1088, 616, 1688, 1066}, - {1312, 784, 1688, 1066}, - {1568, 1040, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_2[]= /* TW: New */ -{ - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, - {1688,1066, 1688,1066}, -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_1[]= /* TW: New - TODO */ -{ /* TW: Temp data, invalid (is identical to 1024x768) */ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_2[]= /* TW: New - TODO */ -{ /* TW: Temp data, invalid (is identical to 1024x768) */ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New: - from 300 series */ -static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_1[]= -{ - {840, 604,1344, 800}, - {840, 560,1344, 800}, - {840, 604,1344, 800}, - {840, 560,1344, 800}, - {840, 689,1344, 800}, - {1050, 800,1344, 800}, - {1344, 800,1344, 800}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New: - from 300 series */ -static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_2[]= -{ - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {1344, 800,1344, 800}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New: - from 300 series */ -static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_1[]= -{ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New: - from 300 series */ -static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_2[]= -{ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -/* TW: New in 650/LVDS BIOS - pass 1:1 data */ -static const SiS310_LVDSDataStruct SiS310_LVDSXXXxXXXData_1[]= /* TW: New */ -{ - { 800, 449, 800, 449}, - { 800, 449, 800, 449}, - { 900, 449, 900, 449}, - { 900, 449, 900, 449}, - { 800, 525, 800, 525}, - {1056, 628,1056, 628}, - {1344, 806,1344, 806}, - {1688, 806,1688, 806} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS640x480Data_1[]= /* TW: New */ -{ - {800, 449, 800, 449}, - {800, 449, 800, 449}, - {800, 449, 800, 449}, - {800, 449, 800, 449}, - {800, 525, 800, 525}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628}, - {1056, 628,1056, 628} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_1[]= /* TW: New */ -{ - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 438,1344, 806}, - {840, 409,1344, 806}, - {840, 518,1344, 806}, - {1050, 638,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_2[]= /* TW: New */ -{ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_1[]= /* TW: New */ -{ /* TW: Might be temporary (invalid) data */ - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {1008, 416, 1688, 1066}, - {1008, 366, 1688, 1066}, - {1200, 530, 1688, 1066}, - {1088, 616, 1688, 1066}, - {1312, 784, 1688, 1066}, - {1568, 1040, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_2[]= /* TW: New */ -{ /* TW: Temporary data. Not valid */ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_1[]= /* TW: New */ -{ /* TW: Temporary data. Not valid */ - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {1344, 806,1344, 806}, - {800, 449,1280, 801}, - {800, 525,1280, 813} -}; - -static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_2[]= /* TW: New */ -{ /* TW: Temporary data. Not valid */ - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - -static const SiS310_LVDSDataStruct SiS310_CHTVUNTSCData[]= /* TW: New */ -{ - { 840, 600, 840, 600}, - { 840, 600, 840, 600}, - { 840, 600, 840, 600}, - { 840, 600, 840, 600}, - { 784, 600, 784, 600}, - {1064, 750,1064, 750}, - {1160, 945,1160, 945} /* TW: For Ch7019 1024 */ -}; - -static const SiS310_LVDSDataStruct SiS310_CHTVONTSCData[]= /* TW: New */ -{ - { 840, 525, 840, 525}, - { 840, 525, 840, 525}, - { 840, 525, 840, 525}, - { 840, 525, 840, 525}, - { 784, 525, 784, 525}, - {1040, 700,1040, 700}, - {1160, 840,1160, 840} /* TW: For Ch7019 1024 */ -}; - -static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]= /* TW: New */ +static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]= { {1008, 625,1008, 625}, {1008, 625,1008, 625}, @@ -2092,10 +1039,10 @@ static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]= /* TW: New */ {1008, 625,1008, 625}, { 840, 625, 840, 625}, { 960, 750, 960, 750}, - {1400,1000,1400,1000} /* TW: For Ch7019 1024 */ + {1400,1000,1400,1000} }; -static const SiS310_LVDSDataStruct SiS310_CHTVOPALData[]= /* TW: New */ +static const SiS310_LVDSDataStruct SiS310_CHTVOPALData[]= { {1008, 625,1008, 625}, {1008, 625,1008, 625}, @@ -2103,10 +1050,10 @@ static const SiS310_LVDSDataStruct SiS310_CHTVOPALData[]= /* TW: New */ {1008, 625,1008, 625}, { 840, 625, 840, 625}, { 944, 625, 944, 625}, - {1400, 875,1400, 875} /* TW: For Ch7019 1024 */ + {1400, 875,1400, 875} }; -static const SiS310_LVDSDataStruct SiS310_CHTVUPALMData[]= /* TW: New */ +static const SiS310_LVDSDataStruct SiS310_CHTVUPALMData[]= { { 840, 600, 840, 600}, { 840, 600, 840, 600}, @@ -2114,10 +1061,10 @@ static const SiS310_LVDSDataStruct SiS310_CHTVUPALMData[]= /* TW: New */ { 840, 600, 840, 600}, { 784, 600, 784, 600}, {1064, 750,1064, 750}, - {1160, 945,1160, 945} /* TW: For Ch7019 1024 */ + {1160, 945,1160, 945} }; -static const SiS310_LVDSDataStruct SiS310_CHTVOPALMData[]= /* TW: New */ +static const SiS310_LVDSDataStruct SiS310_CHTVOPALMData[]= { { 840, 525, 840, 525}, { 840, 525, 840, 525}, @@ -2125,10 +1072,10 @@ static const SiS310_LVDSDataStruct SiS310_CHTVOPALMData[]= /* TW: New */ { 840, 525, 840, 525}, { 784, 525, 784, 525}, {1040, 700,1040, 700}, - {1160, 840,1160, 840} /* TW: For Ch7019 1024 */ + {1160, 840,1160, 840} }; -static const SiS310_LVDSDataStruct SiS310_CHTVUPALNData[]= /* TW: New */ +static const SiS310_LVDSDataStruct SiS310_CHTVUPALNData[]= { {1008, 625,1008, 625}, {1008, 625,1008, 625}, @@ -2136,10 +1083,10 @@ static const SiS310_LVDSDataStruct SiS310_CHTVUPALNData[]= /* TW: New */ {1008, 625,1008, 625}, { 840, 625, 840, 625}, { 960, 750, 960, 750}, - {1400,1000,1400,1000} /* TW: For Ch7019 1024 */ + {1400,1000,1400,1000} }; -static const SiS310_LVDSDataStruct SiS310_CHTVOPALNData[]= /* TW: New */ +static const SiS310_LVDSDataStruct SiS310_CHTVOPALNData[]= { {1008, 625,1008, 625}, {1008, 625,1008, 625}, @@ -2147,10 +1094,10 @@ static const SiS310_LVDSDataStruct SiS310_CHTVOPALNData[]= /* TW: New */ {1008, 625,1008, 625}, { 840, 625, 840, 625}, { 944, 625, 944, 625}, - {1400, 875,1400, 875} /* TW: For Ch7019 1024 */ + {1400, 875,1400, 875} }; -static const SiS310_LVDSDataStruct SiS310_CHTVSOPALData[]= /* TW: New (super overscan - no effect on 7019) */ +static const SiS310_LVDSDataStruct SiS310_CHTVSOPALData[]= /* TW: (super overscan - no effect on 7019) */ { {1008, 625,1008, 625}, {1008, 625,1008, 625}, @@ -2167,9 +1114,7 @@ typedef struct _SiS310_LVDSDesStruct USHORT LCDVDES; } SiS310_LVDSDesStruct; -/* TW: PanelType arrays taken from 650/LVDS BIOS 1.10.0 */ - -static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]= /* 800x600 */ { { 0, 0}, { 0, 0}, @@ -2182,7 +1127,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]= /* 1024x768 */ { { 0, 0}, { 0, 0}, @@ -2195,7 +1140,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]= /* 1280x1024 */ { { 0, 0}, { 0, 0}, @@ -2210,7 +1155,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]= /* TW: New */ }; -static const SiS310_LVDSDesStruct SiS310_PanelType03_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType03_1[]= { { 0, 0}, { 0, 0}, @@ -2223,7 +1168,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType03_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType04_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType04_1[]= { {1343, 798}, {1343, 794}, @@ -2236,7 +1181,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType04_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType05_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType05_1[]= { {1343, 798}, {1343, 794}, @@ -2249,7 +1194,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType05_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType06_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType06_1[]= { {1343, 798}, {1343, 794}, @@ -2262,7 +1207,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType06_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType07_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType07_1[]= { {1343, 798}, {1343, 794}, @@ -2275,7 +1220,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType07_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType08_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType08_1[]= /* 1400x1050 */ { { 0, 0}, { 0, 0}, @@ -2290,58 +1235,61 @@ static const SiS310_LVDSDesStruct SiS310_PanelType08_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType09_1[]= /* TW: New - to check (1280x768) */ +static const SiS310_LVDSDesStruct SiS310_PanelType09_1[]= /* 1280x768 */ { - { 0, 448}, - { 0, 448}, - { 0, 448}, - { 0, 448}, - { 0, 524}, - { 0, 627}, - { 0, 805}, - { 0, 805}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0a_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0a_1[]= /* 1600x1200 */ { - {1059, 626}, - {1059, 624}, - {1059, 626}, - {1059, 624}, - {1059, 624}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0b_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0b_1[]= /* 640x480_2 */ { - {1343, 798}, - {1343, 794}, - {1343, 798}, - {1343, 794}, - {1343, 0}, - {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 8, 524}, + { 0, 524} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0c_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0c_1[]= /* 640x480_3 */ { - {1343, 798}, - {1343, 794}, - {1343, 798}, - {1343, 794}, - {1343, 0}, - {1343, 0}, - { 0, 805}, - { 0, 794}, - { 0, 0} + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 0, 524}, + { 8, 524}, + { 0, 524} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]= { {1343, 798}, {1343, 794}, @@ -2354,7 +1302,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0e_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0e_1[]= { {1343, 798}, {1343, 794}, @@ -2367,7 +1315,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0e_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0f_1[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0f_1[]= { {1343, 798}, {1343, 794}, @@ -2380,7 +1328,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0f_1[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType00_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType00_2[]= { {980, 528}, {980, 503}, @@ -2393,7 +1341,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType00_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType01_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType01_2[]= { {1152, 622}, {1152, 597}, @@ -2406,7 +1354,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType01_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType02_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType02_2[]= { {1368, 754}, {1368, 729}, @@ -2421,7 +1369,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType02_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType03_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType03_2[]= { { 0, 0}, { 0, 0}, @@ -2432,7 +1380,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType03_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType04_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType04_2[]= { { 0, 0}, { 0, 0}, @@ -2445,7 +1393,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType04_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType05_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType05_2[]= { {1152, 622}, {1152, 597}, @@ -2458,7 +1406,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType05_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType06_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType06_2[]= { {1152, 622}, {1152, 597}, @@ -2471,7 +1419,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType06_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType07_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType07_2[]= { {1152, 622}, {1152, 597}, @@ -2484,8 +1432,20 @@ static const SiS310_LVDSDesStruct SiS310_PanelType07_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType08_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType08_2[]= /* 1400x1050 */ { + {1308, 741}, + {1308, 716}, + {1308, 741}, + {1308, 716}, + {1308, 781}, + {1388, 841}, + {1500, 925}, + {1628,1053}, + { 0,1065}, + { 0, 0}, + { 0, 0} +#if 0 {976, 527}, {976, 502}, {976, 527}, @@ -2495,34 +1455,37 @@ static const SiS310_LVDSDesStruct SiS310_PanelType08_2[]= /* TW: New */ { 0, 627}, { 0, 0}, { 0, 0} +#endif }; -static const SiS310_LVDSDesStruct SiS310_PanelType09_2[]= /* TW: New - to check (1280x768) */ +static const SiS310_LVDSDesStruct SiS310_PanelType09_2[]= /* 1280x768 */ { - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0} + {1083, 622}, + {1083, 597}, + {1083, 622}, + {1083, 597}, + {1083, 662}, + {1163, 722}, + {1286, 805}, + { 0, 794}, + { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0a_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0a_2[]= /* 1600x1200 */ { - {976, 527}, - {976, 502}, - {976, 527}, - {976, 502}, - {976, 567}, - { 0, 627}, - { 0, 627}, - { 0, 0}, - { 0, 0} + {1568, 850}, + {1568, 825}, + {1568, 850}, + {1568, 825}, + {1568, 890}, + {1648, 950}, + {1760,1034}, + {1888,1162}, + {1948,1175}, + { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]= /* 640x480_2 */ { {1152, 622}, {1152, 597}, @@ -2535,7 +1498,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]= /* 640x480_3 */ { {1152, 622}, {1152, 597}, @@ -2548,7 +1511,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0d_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0d_2[]= { {1152, 622}, {1152, 597}, @@ -2561,7 +1524,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0d_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0e_2[]= /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0e_2[]= { {1152, 622}, {1152, 597}, @@ -2574,7 +1537,7 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0e_2[]= /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = /* TW: New */ +static const SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = { {1152, 622}, {1152, 597}, @@ -2587,156 +1550,6 @@ static const SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = /* TW: New */ { 0, 0} }; -static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]= /* TW: New */ -{ /* 1024x768 - Checked (1.10.6s) */ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]= /* TW: New */ -{ /* 1024x768 - Checked (1.10.6s) */ - { 1184, 622 }, - { 1184, 597 }, - { 1184, 622 }, - { 1184, 597 }, - { 1152, 622 }, - { 1232, 722 }, - { 0, 0 }, - { 0, 794 }, - { 0, 0 } -}; - -static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]= /* TW: New */ -{ /* 1280x1024 - Checked (1.10.6s) */ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]= /* TW: New */ -{ /* 1280x1024 - Checked (1.10.6s) */ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]= /* TW: New */ -{ /* 1400x1050 - Checked (1.10.6s) */ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]= /* TW: New */ -{ /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */ - { 808 , 740}, - { 0 , 715}, - { 632 , 740}, - { 632 , 715}, - { 1307, 780}, - { 1387,1157}, - { 1499, 924}, - { 1627,1052}, - { 0 , 0} -}; - -static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= /* TW: New */ -{ /* 1600x1200 - Checked (1.10.6s) */ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= /* TW: New */ -{ /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid */ - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0}, - { 0 , 0} -}; - -static const SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[]= -{ - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0} -}; - -static const SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[]= -{ - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0} -}; - -static const SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[]= -{ - {256, 0}, - {256, 0}, - {256, 0}, - {256, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0} -}; - -static const SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[]= -{ - {256, 0}, - {256, 0}, - {256, 0}, - {256, 0}, - { 0, 0}, - { 0, 0}, - { 0, 0} -}; - typedef struct _SiS310_Part2PortTblStruct { UCHAR CR[12]; @@ -2756,16 +1569,15 @@ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] = }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] = -{ /* TW: Temporary data, invalid */ - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +{ /* TW: BIOS data invalid, last row taken from _3 */ + {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}}, + {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}}, + {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}} }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] = @@ -2782,16 +1594,17 @@ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] = }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] = -{ /* TW: Temporary data, invalid */ - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +{ + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}} }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] = @@ -2802,7 +1615,8 @@ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] = {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}}, {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}}, {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}}, - {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, /* others */ +/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24 my */ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} }; @@ -2834,21 +1648,23 @@ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] = }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] = -{ /* TW: Temporary data, invalid */ - {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, - {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, - {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, - {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, - {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, - {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}}, - {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}}, - {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +{ + {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x3A,0x1B,0x54,0x7A,0x48,0x80,0x24,0x52,0x30,0xA3,0x3A,0x02}}, + {{0x36,0x1B,0x90,0xB6,0x84,0xA8,0x24,0x7A,0x30,0xCB,0x62,0x02}}, + {{0x3A,0x1C,0xE4,0x0A,0xD8,0xE0,0x24,0xB2,0x30,0x03,0x9A,0x02}}, + {{0x4A,0x24,0x64,0x8A,0x58,0x20,0x34,0xF2,0x30,0x43,0xDA,0x52}}, + {{0x47,0x24,0x71,0x97,0x65,0x3E,0x34,0x10,0x40,0x61,0xF8,0x02}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}} }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] = -{ /* TW: Data from 650/301LVx 1.10.6s */ +{ +#if 1 /* Data from 650/301LVx 1.10.6s and others */ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, @@ -2858,56 +1674,58 @@ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] = {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}} -#if 0 /* TW: Data from 650/301LV */ - {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, - {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, - {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, - {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, - {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +#endif +#if 0 /* Data from my 301LV */ + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, /* TEST */ + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, + {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}} #endif }; /* 1 2 4 5 6 1c 1d 1f 20 21 23 25 */ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] = -{ /* TW: Temporary data, invalid */ - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}} +{ + {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}}, + {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}} }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] = -{ /* TW: Temporary data, invalid */ - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}} +{ + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}} }; static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] = -{ /* TW: Temporary data, invalid */ - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, - {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}} +{ + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}, + {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}} }; typedef struct _SiS310_LCDACRT1DataStruct @@ -2944,7 +1762,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1[] = }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[]= -{ /* TW: Checked (1.10.6s) */ +{ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f, 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05, 0x00}}, @@ -2969,7 +1787,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1[]= -{ /* Checked (1.10.6s) */ +{ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f, 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06, 0x00}}, @@ -2997,7 +1815,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1[]= -{ /* Checked (1.10.6s) */ +{ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f, 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05, 0x00}}, @@ -3090,7 +1908,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1_H[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[]= -{ /* TW: Checked (1.10.6s) */ +{ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f, 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44, 0x00}}, @@ -3115,7 +1933,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[]= -{ /* Checked (1.10.6s) */ +{ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f, 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05, 0x00}}, @@ -3140,7 +1958,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1_H[]= -{ /* Checked (1.10.6s) */ +{ {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05, 0x00}}, @@ -3233,7 +2051,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2[]= -{ /* Checked (1.10.6s) */ +{ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06, 0x00}}, @@ -3258,7 +2076,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2[]= -{ /* Checked (1.10.6s) */ +{ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06, 0x00}}, @@ -3283,7 +2101,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2[]= -{ /* Checked (1.10.6s) */ +{ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a, 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03, 0x00}}, @@ -3376,7 +2194,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2_H[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2_H[]= -{ /* Checked (1.10.6s) */ +{ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb, 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01, 0x00 }}, @@ -3401,7 +2219,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2_H[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[]= -{ /* Checked (1.10.6s) */ +{ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb, 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01, 0x00 }}, @@ -3426,7 +2244,7 @@ static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[]= }; static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2_H[]= -{ /* Checked (1.10.6s) */ +{ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a, 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06, 0x00}}, @@ -3495,32 +2313,7 @@ typedef struct _SiS310_LVDSCRT1DataStruct UCHAR CR[15]; } SiS310_LVDSCRT1DataStruct; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1320x480_1[] = -{ - {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, - 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, - 0x00 }}, - {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, - 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, - 0x00 }}, - {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, - 0x00 }}, - {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, - 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, - 0x00 }}, - {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e, - 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, - 0x00 }}, - {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, - 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, - 0x01 }}, - {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, - 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, - 0x00 }} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] = { {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f, 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, @@ -3542,7 +2335,7 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] = /* TW: Ne 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] = { {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f, 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05, @@ -3567,35 +2360,35 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] = /* TW: 0x01}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] = { - {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, + {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f, 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, + 0x00}}, + {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f, 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, + 0x00}}, + {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f, 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, + 0x00}}, + {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f, 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e, + 0x00}}, + {{0x7e,0x4f,0x82,0x58,0x04,0x08,0x3e, 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06, - 0x00 }}, - {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0, + 0x00}}, + {{0x92,0x63,0x96,0x6c,0x18,0x80,0xf0, 0x58,0x8c,0x57,0x81,0x20,0x00,0x06, - 0x01 }}, - {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5, + 0x01}}, + {{0xae,0x7f,0x92,0x88,0x94,0x28,0xf5, 0x00,0x84,0xff,0x29,0x10,0x00,0x02, - 0x01 }}, - {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, + 0x01}}, + {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a, 0x00,0x84,0xff,0x29,0x09,0x00,0x07, 0x01}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] = { {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f, 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, @@ -3617,7 +2410,7 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] = /* TW: 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] = { {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f, 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05, @@ -3642,32 +2435,32 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] = /* TW 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] = { - {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, + {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f, 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, - 0x00 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, + 0x00}}, + {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f, 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, - 0x00 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, + 0x00}}, + {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f, 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, - 0x00 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, + 0x00}}, + {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f, 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, - 0x01 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e, + 0x01}}, + {{0x56,0x27,0x9a,0x31,0x1c,0x08,0x3e, 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05, - 0x00 }}, - {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0, + 0x00}}, + {{0x60,0x31,0x84,0x3a,0x86,0x80,0xf0, 0x58,0x8c,0x57,0x81,0x20,0x00,0x01, - 0x01 }}, - {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5, + 0x01}}, + {{0x6e,0x3f,0x92,0x48,0x94,0x28,0xf5, 0x00,0x84,0xff,0x29,0x10,0x00,0x01, - 0x01 }} + 0x01}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]= /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]= { {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, 0xff,0x84,0x8f,0x73,0x00,0x00,0x06, @@ -3689,7 +2482,7 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]= /* TW: New 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] = { {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06, @@ -3714,35 +2507,35 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] = /* TW: N 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] = { - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e, - 0x03,0x87,0xdf,0x29,0x01,0x00,0x03, - 0x00 }}, + {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92, + 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92, + 0xaf,0x83,0x44,0x43,0x21,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92, + 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92, + 0xaf,0x83,0x44,0x43,0x21,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92, + 0xf0,0x84,0x85,0x84,0x11,0x00,0x02, + 0x01}}, {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4, 0x3f,0x83,0x57,0x29,0x01,0x00,0x03, - 0x01 }}, + 0x01}}, {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4, 0x93,0x87,0xff,0x29,0x21,0x00,0x07, - 0x01 }}, - {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, + 0x01}}, + {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a, 0x00,0x84,0xff,0x29,0x09,0x00,0x07, 0x01}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] = { {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e, 0xff,0x84,0x8f,0x73,0x00,0x00,0x01, @@ -3764,7 +2557,7 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] = /* TW: 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] = { {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb, 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01, @@ -3789,86 +2582,61 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] = /* TW: 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] = /* TW: New */ -{ - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e, - 0x03,0x87,0xdf,0x29,0x01,0x00,0x06, - 0x00 }}, - {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4, - 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, - 0x01 }}, - {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4, - 0x93,0x87,0xff,0x29,0x21,0x00,0x06, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] = { - {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, - 0x00}}, - {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, - 0x00}}, - {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, - 0x00}}, - {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, - 0x00}}, - {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, - 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05, - 0x00}}, - {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, - 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92, + 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06, 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92, + 0xaf,0x83,0x44,0x43,0x21,0x00,0x06, 0x01}}, - {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x07, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] = /* TW: New */ -{ - {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, - 0x00}}, - {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, - 0x00}}, - {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, - 0x00}}, - {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, - 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, - 0x00}}, - {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e, - 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, - 0x00}}, - {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0, - 0x58,0x8c,0x57,0x73,0x20,0x00,0x01, + {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92, + 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06, + 0x01}}, + {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92, + 0xfa,0x83,0x44,0x43,0x31,0x00,0x06, + 0x01}}, + {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92, + 0xf0,0x84,0x85,0x84,0x11,0x00,0x06, + 0x01}}, + {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, 0x01}}, - {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + {{0x8e,0x3f,0x92,0x59,0x07,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x06, 0x01}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] = { + {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x5e,0x81,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f, + 0xdf,0x82,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0, + 0x57,0x8e,0x57,0x67,0x20,0x00,0x06, + 0x01}}, + {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf1, + 0xff,0x86,0xff,0x0f,0x10,0x00,0x02, + 0x01,}}, + {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0xde, + 0xff,0x86,0xff,0x0f,0x01,0x00,0x07, + 0x01}}, + {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10, + 0x19,0x80,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +#if 0 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, 0x00}}, @@ -3896,11 +2664,40 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] = /* TW: {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10, 0x1a,0x80,0x19,0x29,0x0f,0x00,0x03, 0x00}} +#endif }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] = { {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, + 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f, + 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f, + 0xdf,0x86,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0, + 0x57,0x8e,0x57,0x67,0x20,0x00,0x01, + 0x01}}, + {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf1, + 0xff,0x86,0xff,0x0f,0x10,0x00,0x01, + 0x01}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a, + 0x02,0x86,0xff,0x0f,0x09,0x00,0x05, + 0x01}}, + {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10, + 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05, + 0x00}} +#if 0 + {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, 0x00}}, {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, @@ -3927,10 +2724,39 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] = /* TW {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10, 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05, 0x00}} +#endif }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] = { + {{0xce,0x72,0x91,0x84,0x92,0x28,0x92, + 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x84,0x92,0x28,0x92, + 0xbe,0x82,0x44,0x43,0x01,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x84,0x92,0x28,0x92, + 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x84,0x92,0x28,0x92, + 0xbe,0x82,0x44,0x43,0x01,0x00,0x02, + 0x01}}, + {{0xce,0x72,0x91,0x84,0x92,0x28,0x92, + 0xff,0x83,0x85,0x84,0x11,0x00,0x02, + 0x01}}, + {{0xce,0x63,0x92,0x8e,0x1c,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x03, + 0x01}}, + {{0xce,0x7f,0x92,0x9c,0x0a,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x07, + 0x01}}, + {{0xce,0x9f,0x92,0xac,0x1a,0x28,0x5a, + 0x13,0x87,0xff,0x29,0x29,0x00,0x07, + 0x01}}, + {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10, + 0x20,0x84,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +#if 0 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, 0x00}}, @@ -3958,10 +2784,39 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] = /* TW: {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10, 0x20,0x84,0x19,0x29,0x0f,0x00,0x03, 0x00}} +#endif }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] = { + {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92, + 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06, + 0x01}}, + {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92, + 0xbe,0x82,0x44,0x43,0x01,0x00,0x06, + 0x01}}, + {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92, + 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06, + 0x01}}, + {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92, + 0xbe,0x82,0x44,0x43,0x01,0x00,0x06, + 0x01}}, + {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92, + 0xff,0x83,0x85,0x84,0x11,0x00,0x06, + 0x01}}, + {{0x9c,0x31,0x80,0x5c,0x8a,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, + 0x01}}, + {{0x8e,0x3f,0x92,0x5c,0x0a,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x06, + 0x01}}, + {{0x7e,0x4f,0x82,0x5c,0x0a,0x28,0x5a, + 0x13,0x87,0xff,0x29,0x29,0x00,0x06, + 0x01}}, + {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10, + 0x20,0x84,0x19,0x29,0x0f,0x00,0x05, + 0x00}} +#if 0 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, 0x00}}, @@ -3989,440 +2844,147 @@ static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] = /* T {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10, 0x20,0x84,0x19,0x29,0x0f,0x00,0x05, 0x00}} +#endif }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1[] = /* TW: New */ -{ /* TW: Temp data, invalid */ - {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, - 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, - 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, - 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, - 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, - 0x00 }}, - {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e, - 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06, - 0x00 }}, - {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0, - 0x58,0x8c,0x57,0x81,0x20,0x00,0x06, - 0x01 }}, - {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5, - 0x00,0x84,0xff,0x29,0x10,0x00,0x02, - 0x01 }}, - {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, - 0x00,0x84,0xff,0x29,0x09,0x00,0x07, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1_H[] = /* TW: New */ -{ /* TW: Temp data, invalid */ - {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, - 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, - 0x00 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, - 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, - 0x00 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, - 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, - 0x00 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, - 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, - 0x01 }}, - {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e, - 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05, - 0x00 }}, - {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0, - 0x58,0x8c,0x57,0x81,0x20,0x00,0x01, - 0x01 }}, - {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5, - 0x00,0x84,0xff,0x29,0x10,0x00,0x01, - 0x01 }} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2[] = /* TW: New */ -{ /* TW: Temp data, invalid */ - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, - 0x00 }}, - {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e, - 0x03,0x87,0xdf,0x29,0x01,0x00,0x03, - 0x00 }}, - {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4, - 0x3f,0x83,0x57,0x29,0x01,0x00,0x03, - 0x01 }}, - {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4, - 0x93,0x87,0xff,0x29,0x21,0x00,0x07, - 0x01 }}, - {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, - 0x00,0x84,0xff,0x29,0x09,0x00,0x07, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2_H[] = /* TW: New */ -{ /* TW: Temp data, invalid */ - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, - 0x00 }}, - {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e, - 0x03,0x87,0xdf,0x29,0x01,0x00,0x06, - 0x00 }}, - {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4, - 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, - 0x01 }}, - {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4, - 0x93,0x87,0xff,0x29,0x21,0x00,0x06, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_1[] = -{ - {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, - 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, - 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, - 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, - 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba, - 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01, - 0x00}}, - {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1, - 0xae,0x85,0x57,0x1f,0x30,0x00,0x26, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1, - 0xae,0x85,0x57,0x1f,0x30,0x00,0x02, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_1_H[] = -{ - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, - 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, - 0x00}}, - {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, - 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2[] = -{ - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x02, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2_H[] = -{ - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x01, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1[] = -{ - {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, - 0x00}}, - {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e, - 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, - 0x00}}, - {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, - 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1_H[] = -{ - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, - 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, - 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, - 0x00}}, - {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, - 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, - 0x00}}, - {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, - 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2[] = -{ - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, - 0x00}}, - {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x02, - 0x01}}, - {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x02, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2_H[] = -{ - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, - 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, - 0x00}}, - {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, - 0xae,0x84,0x57,0x25,0x30,0x00,0x01, - 0x01}}, - {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, - 0x02,0x88,0xff,0x25,0x10,0x00,0x01, - 0x01}} -}; - -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] = -{ /* TW: Temporary data - invalid */ - {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, - 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] = +{ + {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f, + 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06, 0x00}}, - {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, - 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f, + 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06, 0x00}}, - {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, - 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f, + 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06, 0x00}}, - {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, - 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f, + 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06, 0x00}}, - {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f, - 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05, + {{0x83,0x4f,0x87,0x51,0x09,0x10,0x3e, + 0xe0,0x84,0xdf,0x11,0x00,0x00,0x06, 0x00}}, - {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0, - 0x5a,0x8e,0x57,0x67,0x20,0x00,0x06, + {{0x97,0x63,0x9b,0x65,0x1d,0x88,0xf0, + 0x58,0x8c,0x57,0x89,0x20,0x00,0x06, 0x01}}, - {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5, - 0x02,0x86,0xff,0x0f,0x10,0x00,0x02, + {{0xb3,0x7f,0x97,0x81,0x99,0x30,0xf5, + 0x00,0x84,0xff,0x31,0x10,0x00,0x02, 0x01}}, - {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a, - 0x02,0x86,0xff,0x0f,0x09,0x00,0x07, + {{0xd3,0x9f,0x97,0xa1,0x19,0x30,0x5a, + 0x00,0x84,0xff,0x31,0x09,0x00,0x07, 0x01}}, - {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10, - 0x1a,0x80,0x19,0x29,0x0f,0x00,0x03, + {{0xe2,0xae,0x86,0xb0,0x88,0x4a,0x10, + 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x03, + 0x00}}, + {{0xfb,0xc7,0x9f,0xc9,0x81,0xe0,0x10, + 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x07, 0x00}} }; static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] = -{ /* TW: Temporary data - invalid */ - {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, - 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, +{ + {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f, + 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01, 0x00}}, - {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, - 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f, + 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01, 0x00}}, - {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f, - 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05, + {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f, + 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01, 0x00}}, - {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, - 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f, + 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01, 0x00}}, - {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f, - 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05, + {{0x5b,0x27,0x9f,0x29,0x01,0x10,0x3e, + 0xe0,0x84,0xdf,0x11,0x00,0x00,0x01, 0x00}}, - {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0, - 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01, + {{0x65,0x31,0x89,0x33,0x8b,0x88,0xf0, + 0x58,0x8c,0x57,0x89,0x20,0x00,0x01, 0x01}}, - {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5, - 0x02,0x86,0xff,0x0f,0x10,0x00,0x01, + {{0x73,0x3f,0x97,0x41,0x99,0x30,0xf5, + 0x00,0x84,0xff,0x31,0x10,0x00,0x01, 0x01}}, - {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a, - 0x02,0x86,0xff,0x0f,0x09,0x00,0x05, + {{0x83,0x4f,0x87,0x51,0x09,0x30,0x5a, + 0x00,0x84,0xff,0x31,0x09,0x00,0x06, 0x01}}, - {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10, - 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05, + {{0x8a,0x56,0x8e,0x58,0x10,0x4a,0x10, + 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x06, + 0x00}}, + {{0x97,0x63,0x9b,0x65,0x1d,0xe0,0x10, + 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x06, 0x00}} }; static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] = -{ /* TW: Temporary data - invalid */ - {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, - 0x00}}, - {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, +{ + {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96, + 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07, 0x01}}, - {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, - 0x00}}, - {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, - 0x00}}, - {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e, - 0x03,0x87,0xdf,0x29,0x01,0x00,0x03, - 0x00}}, - {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4, - 0x3f,0x83,0x57,0x29,0x01,0x00,0x07, + {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96, + 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07, 0x01}}, - {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4, - 0x93,0x87,0xff,0x29,0x21,0x00,0x07, + {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96, + 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07, 0x01}}, - {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a, - 0x13,0x87,0xff,0x29,0x29,0x00,0x03, + {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96, + 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07, 0x01}}, - {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10, - 0x20,0x84,0x19,0x29,0x0f,0x00,0x03, + {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96, + 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x07, + 0x01}}, + {{0xfb,0x63,0x9f,0x9a,0x92,0xe0,0xd4, + 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x07, + 0x01}}, + {{0xfb,0x7f,0x9f,0xa8,0x80,0xe0,0xd4, + 0xef,0x83,0xff,0xe1,0x21,0x00,0x03, + 0x01}}, + {{0xfb,0x9f,0x9f,0xb8,0x90,0xe0,0x5a, + 0x6f,0x83,0xff,0xe1,0x29,0x00,0x03, + 0x01}}, + {{0xfb,0xae,0x9f,0xbf,0x97,0xe0,0x10, + 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x03, + 0x00}}, + {{0xfb,0xc7,0x9f,0xc9,0x84,0xe0,0x10, + 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x07, 0x00}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] = /* TW: New */ -{ /* TW: Temporary data - invalid */ - {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, - 0x00}}, - {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, - 0x00}}, - {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, - 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, - 0x00}}, - {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, - 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, - 0x00}}, - {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e, - 0x03,0x87,0xdf,0x29,0x01,0x00,0x06, - 0x00}}, - {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4, - 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] = +{ + {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96, + 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02, 0x01}}, - {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4, - 0x93,0x87,0xff,0x29,0x21,0x00,0x06, + {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96, + 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02, 0x01}}, - {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a, - 0x13,0x87,0xff,0x29,0x29,0x00,0x06, + {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96, + 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02, 0x01}}, - {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10, - 0x20,0x84,0x19,0x29,0x0f,0x00,0x05, + {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96, + 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02, + 0x01}}, + {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96, + 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x02, + 0x01}}, + {{0xc9,0x31,0x8d,0x68,0x00,0xe0,0xd4, + 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x03, + 0x01}}, + {{0xbb,0x3f,0x9f,0x68,0x80,0xe0,0xd4, + 0xef,0x83,0xff,0xe1,0x21,0x00,0x02, + 0x01}}, + {{0xab,0x4f,0x8f,0x68,0x80,0xe0,0x5a, + 0x6f,0x83,0xff,0xe1,0x29,0x00,0x02, + 0x01}}, + {{0xa3,0x56,0x87,0x67,0x9f,0xe0,0x10, + 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x06, + 0x00}}, + {{0x97,0x63,0x9b,0x68,0x00,0xe0,0x10, + 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x02, 0x00}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = { {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01, @@ -4442,12 +3004,12 @@ static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = /* TW: New * {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0, 0x7a,0x8f,0x57,0xed,0x20,0x00,0x06, 0x01 }}, - {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5, /* TW: 1024x768 */ + {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5, 0x36,0x88,0xff,0xb0,0x10,0x00,0x02, 0x01}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = { {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e, 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01, @@ -4467,12 +3029,12 @@ static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = /* TW: New * {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0, 0x78,0x8a,0x57,0xbb,0x20,0x00,0x06, 0x01 }}, - {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5, /* TW: 1024x768 */ + {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5, 0x15,0x88,0xff,0x47,0x70,0x00,0x02, 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = { {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05, @@ -4492,12 +3054,12 @@ static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = /* TW: New */ {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0, 0x90,0x8c,0x57,0xed,0x20,0x00,0x05, 0x01 }}, - {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5, /* TW: 1024x768 */ + {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5, 0x50,0x88,0xff,0xe7,0x10,0x00,0x02, 0x01}} }; -static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = { {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, @@ -4517,12 +3079,12 @@ static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = /* TW: New */ {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0, 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05, 0x01 }}, - {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */ + {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, 0x28,0x88,0xff,0x6a,0x10,0x00,0x02, 0x01 }} }; -static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1SOPAL[] = /* TW: New */ +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1SOPAL[] = { {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, @@ -4542,12 +3104,11 @@ static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1SOPAL[] = /* TW: New * {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0, 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05, 0x01 }}, - {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */ + {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, 0x28,0x88,0xff,0x6a,0x10,0x00,0x02, 0x01 }} }; -/* TW: New data for Chrontel 7019 (From 650/LVDS BIOS 1.10.0) */ typedef struct _SiS310_CHTVRegDataStruct { UCHAR Reg[16]; @@ -4670,4 +3231,3 @@ static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54} static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52}; -/* TW: New end */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile index 2b4b45271..4cbe4186e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile,v 1.9 1999/08/14 10:49:54 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile,v 1.32 2003/04/21 12:32:11 sven Exp $ XCOMM XCOMM This is an Imakefile for the SIS driver. XCOMM @@ -6,24 +6,51 @@ XCOMM #define IHaveModules #include <Server.tmpl> -SRCS = sis_driver.c sis_dac.c sis_accel.c sis_accel2.c -OBJS = sis_driver.o sis_dac.o sis_accel.o sis_accel2.o +/* DRI static build only works on Linux */ +#if !defined(LinuxArchitecture) && !DoLoadableServer && BuildXF86DRI +#undef BuildXF86DRI +#define BuildXF86DRI NO +#endif + +#if BuildXF86DRI +DRISRCS = sis_dri.c +DRIOBJS = sis_dri.o +DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \ + -I$(XTOP)/include +DRIDEFINES = $(GLX_DEFINES) +#endif + +SRCS = sis_driver.c sis_dac.c sis_cursor.c sis_accel.c sis_setup.c\ + sis300_accel.c sis310_accel.c sis_vga.c sis_vb.c\ + sis_opt.c sis_dga.c sis_video.c init.c init301.c sis_shadow.c \ + sis6326_video.c \ + $(DRISRCS) +OBJS = sis_driver.o sis_dac.o sis_cursor.o sis_accel.o sis_setup.o\ + sis300_accel.o sis310_accel.o sis_vga.o sis_vb.o\ + sis_opt.o sis_dga.o sis_video.o init.o init301.o sis_shadow.o \ + sis6326_video.o \ + $(DRIOBJS) #if defined(XF86DriverSDK) INCLUDES = -I. -I../../include #else INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ - -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \ - -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \ - -I$(XF86SRC)/xf24_32bpp \ + -I$(SERVERSRC)/fb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \ + -I$(XF86SRC)/xf24_32bpp \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ - -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ - -I$(XF86SRC)/rac \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(XF86SRC)/vbe \ + -I$(XF86SRC)/rac -I$(XF86SRC)/int10 \ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ - -I$(XTOP)/include/extensions + -I$(XTOP)/include/extensions \ + -I$(SERVERSRC)/render \ + -I$(XF86SRC)/shadowfb \ + $(DRIINCLUDES) #endif +DEFINES = $(DRIDEFINES) + #if MakeHasPosixVariableSubstitutions SubdirLibraryRule($(OBJS)) #endif @@ -34,16 +61,51 @@ ObjectModuleTarget(sis,$(OBJS)) InstallObjectModule(sis,$(MODULEDIR),drivers) +#if !defined(XF86DriverSDK) +InstallModuleManPage(sis) +#endif + DependTarget() InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/sis) InstallDriverSDKNonExecFile(sis.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis300_accel.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis300_accel.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis310_accel.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis310_accel.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_accel.h,$(DRIVERSDKDIR)/drivers/sis) InstallDriverSDKNonExecFile(sis_accel.c,$(DRIVERSDKDIR)/drivers/sis) -InstallDriverSDKNonExecFile(sis_accel2.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(init.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(init.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(init301.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(init301.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(osdef.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(initdef.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(300vtbl.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(310vtbl.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(oem300.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(oem310.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_cursor.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_cursor.h,$(DRIVERSDKDIR)/drivers/sis) InstallDriverSDKNonExecFile(sis_dac.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_dac.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_dga.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_dri.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_dri.h,$(DRIVERSDKDIR)/drivers/sis) InstallDriverSDKNonExecFile(sis_driver.c,$(DRIVERSDKDIR)/drivers/sis) InstallDriverSDKNonExecFile(sis_driver.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_opt.c,$(DRIVERSDKDIR)/drivers/sis) InstallDriverSDKNonExecFile(sis_regs.h,$(DRIVERSDKDIR)/drivers/sis) -InstallDriverSDKNonExecFile(sis_regs2.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_setup.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_shadow.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_shadow.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_vb.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_vb.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_vga.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_video.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis6326_video.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(sis_accel.c,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(vgatypes.h,$(DRIVERSDKDIR)/drivers/sis) +InstallDriverSDKNonExecFile(vstruct.h,$(DRIVERSDKDIR)/drivers/sis) InstallDriverSDKObjectModule(sis,$(DRIVERSDKMODULEDIR),drivers) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/init.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.c index 74c302c8f..a026af376 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/init.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.c @@ -1,23 +1,17 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.6 2003/02/04 02:44:28 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.13 2003/07/28 12:39:45 twini Exp $ */ /* - * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330 + * Mode switching code (CRT1 section) for + * SiS 300/540/630/730/315/550/650/M650/651/M652/740/330/660/M660/760 * (Universal module for Linux kernel framebuffer and XFree86 4.x) * * Assembler-To-C translation - * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net> - * Minor parts Copyright SiS, Inc. + * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net> + * Formerly based on non-functional code-fragements by SiS, Inc. * - * Based on BIOS - * 1.10.07, 1.10a for SiS650/LVDS+CH7019 - * 1.11.05 for 650/LVDS (w/o Chrontel) - * 1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for SiS650/301(B/LV) - * 2.04.50 (I) and 2.04.5c (II) for SiS630/301(B) - * 2.06.50 for 630/301B (dual VGA) - * 2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005 - * 2.04.5c, 2.04.6c for 730+LVDS+CH7005 - * 1.09b for 315/301(B) - * 1.16.51 for 300+301LVX (ECS A907) - * 1.01.03 for 330 (Xabre 400) + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -60,12 +54,12 @@ #ifdef LINUX_XF86 BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); -DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn); -#ifdef SISDUALHEAD /* TW: For dual head */ +DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi); +#ifdef SISDUALHEAD BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, - ScrnInfoPtr pScrn, DisplayModePtr mode); + ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); #endif /* dual head */ #endif /* linux_xf86 */ @@ -89,96 +83,215 @@ BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, static ULONG GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); -static void DelaySeconds(int seconds); -void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code); - -#ifdef LINUX_XF86 -/* TW: Mode table for X driver */ -const UShort ModeIndex_320x480[] = {0x5a, 0x5b, 0x00, 0x00}; /* DSTN/FSTN */ -const UShort ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c}; -const UShort ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e}; -const UShort ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62}; -const UShort ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35}; -const UShort ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36}; -const UShort ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76}; -const UShort ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63}; -const UShort ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e}; -const UShort ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45}; -const UShort ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64}; -const UShort ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77}; -const UShort ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */ -const UShort ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65}; -const UShort ModeIndex_300_1280x960[] = {0x6e, 0x6f, 0x00, 0x7b}; -const UShort ModeIndex_310_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e}; -const UShort ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */ -const UShort ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b}; -const UShort ModeIndex_1280x768[] = {0x23, 0x24, 0x00, 0x25}; /* 310/325 series only */ -const UShort ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78}; -const UShort ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e}; -const UShort ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 310/325 series only */ -const UShort ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66}; -const UShort ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b}; -const UShort ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00}; -const UShort ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e}; -#endif - static void -DelaySeconds(int seconds) +InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) { - int i; -#ifdef WIN2000 - int j; -#endif - - for (i=0;i<seconds;i++) { -#ifdef TC - delay(1000); -#endif - -#ifdef WIN2000 - for (j=0;j<20000;j++) - VideoPortStallExecution(50); -#endif - -#ifdef WINCE_HEADER -#endif - -#ifdef LINUX_KERNEL -#endif - } -} + SiS_Pr->SiS_StResInfo = SiS_StResInfo; + SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo; + SiS_Pr->SiS_StandTable = SiS_StandTable; + if(HwDeviceExtension->jChipType < SIS_315H) { + SiS_StandTable[0x04].CRTC[4] = 0x2b; + SiS_StandTable[0x05].CRTC[4] = 0x2b; + SiS_StandTable[0x06].CRTC[4] = 0x54; + SiS_StandTable[0x06].CRTC[5] = 0x80; + SiS_StandTable[0x0d].CRTC[4] = 0x2b; + SiS_StandTable[0x0e].CRTC[4] = 0x54; + SiS_StandTable[0x0e].CRTC[5] = 0x80; + SiS_StandTable[0x11].CRTC[4] = 0x54; + SiS_StandTable[0x11].CRTC[5] = 0x80; + SiS_StandTable[0x11].CRTC[16] = 0x83; + SiS_StandTable[0x11].CRTC[17] = 0x85; + SiS_StandTable[0x12].CRTC[4] = 0x54; + SiS_StandTable[0x12].CRTC[5] = 0x80; + SiS_StandTable[0x12].CRTC[16] = 0x83; + SiS_StandTable[0x12].CRTC[17] = 0x85; + SiS_StandTable[0x13].CRTC[5] = 0xa0; + SiS_StandTable[0x17].CRTC[5] = 0xa0; + SiS_StandTable[0x1a].CRTC[4] = 0x54; + SiS_StandTable[0x1a].CRTC[5] = 0x80; + SiS_StandTable[0x1a].CRTC[16] = 0xea; + SiS_StandTable[0x1a].CRTC[17] = 0x8c; + SiS_StandTable[0x1b].CRTC[4] = 0x54; + SiS_StandTable[0x1b].CRTC[5] = 0x80; + SiS_StandTable[0x1b].CRTC[16] = 0xea; + SiS_StandTable[0x1b].CRTC[17] = 0x8c; + SiS_StandTable[0x1c].CRTC[4] = 0x54; + SiS_StandTable[0x1c].CRTC[5] = 0x80; + } else { + SiS_StandTable[0x04].CRTC[4] = 0x2c; + SiS_StandTable[0x05].CRTC[4] = 0x2c; + SiS_StandTable[0x06].CRTC[4] = 0x55; + SiS_StandTable[0x06].CRTC[5] = 0x81; + SiS_StandTable[0x0d].CRTC[4] = 0x2c; + SiS_StandTable[0x0e].CRTC[4] = 0x55; + SiS_StandTable[0x0e].CRTC[5] = 0x81; + SiS_StandTable[0x11].CRTC[4] = 0x55; + SiS_StandTable[0x11].CRTC[5] = 0x81; + SiS_StandTable[0x11].CRTC[16] = 0x82; + SiS_StandTable[0x11].CRTC[17] = 0x84; + SiS_StandTable[0x12].CRTC[4] = 0x55; + SiS_StandTable[0x12].CRTC[5] = 0x81; + SiS_StandTable[0x12].CRTC[16] = 0x82; + SiS_StandTable[0x12].CRTC[17] = 0x84; + SiS_StandTable[0x13].CRTC[5] = 0xb1; + SiS_StandTable[0x17].CRTC[5] = 0xb1; + SiS_StandTable[0x1a].CRTC[4] = 0x55; + SiS_StandTable[0x1a].CRTC[5] = 0x81; + SiS_StandTable[0x1a].CRTC[16] = 0xe9; + SiS_StandTable[0x1a].CRTC[17] = 0x8b; + SiS_StandTable[0x1b].CRTC[4] = 0x55; + SiS_StandTable[0x1b].CRTC[5] = 0x81; + SiS_StandTable[0x1b].CRTC[16] = 0xe9; + SiS_StandTable[0x1b].CRTC[17] = 0x8b; + SiS_StandTable[0x1c].CRTC[4] = 0x55; + SiS_StandTable[0x1c].CRTC[5] = 0x81; + } -void -SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code) -{ - OutPortByte(0x80, code); - DelaySeconds(0x3); + SiS_Pr->SiS_NTSCPhase = SiS_NTSCPhase; + SiS_Pr->SiS_PALPhase = SiS_PALPhase; + SiS_Pr->SiS_NTSCPhase2 = SiS_NTSCPhase2; + SiS_Pr->SiS_PALPhase2 = SiS_PALPhase2; + SiS_Pr->SiS_PALMPhase = SiS_PALMPhase; + SiS_Pr->SiS_PALNPhase = SiS_PALNPhase; + SiS_Pr->SiS_PALMPhase2 = SiS_PALMPhase2; + SiS_Pr->SiS_PALNPhase2 = SiS_PALNPhase2; + SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase; + + SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming; + SiS_Pr->SiS_PALTiming = SiS_PALTiming; + SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing; + SiS_Pr->SiS_HiTVSt2Timing = SiS_HiTVSt2Timing; + SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming; + SiS_Pr->SiS_HiTVExtTiming = SiS_HiTVExtTiming; + SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data; + SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu; + SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text; + + SiS_Pr->SiS_StPALData = SiS_StPALData; + SiS_Pr->SiS_ExtPALData = SiS_ExtPALData; + SiS_Pr->SiS_StNTSCData = SiS_StNTSCData; + SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData; +/* SiS_Pr->SiS_St1HiTVData = SiS_St1HiTVData; */ + SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData; + SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData; + + SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect; + SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting; + + SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data; + SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data; + SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data; + SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data; + SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data; + SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050; + SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200; + SiS_Pr->SiS_ExtLCD1280x768Data = SiS_ExtLCD1280x768Data; + SiS_Pr->SiS_StLCD1280x768Data = SiS_StLCD1280x768Data; + SiS_Pr->SiS_NoScaleData1280x768 = SiS_NoScaleData1280x768; + SiS_Pr->SiS_NoScaleData = SiS_NoScaleData; + + SiS_Pr->SiS_LVDS320x480Data_1 = SiS_LVDS320x480Data_1; + SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1; + SiS_Pr->SiS_LVDS800x600Data_2 = SiS_LVDS800x600Data_2; + SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1; + SiS_Pr->SiS_LVDS1024x768Data_2 = SiS_LVDS1024x768Data_2; + SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1; + SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2; + SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1; + SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2; + SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1; + SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2; + SiS_Pr->SiS_LVDS1280x768Data_1 = SiS_LVDS1280x768Data_1; + SiS_Pr->SiS_LVDS1280x768Data_2 = SiS_LVDS1280x768Data_2; + SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1; + SiS_Pr->SiS_LVDS1024x600Data_2 = SiS_LVDS1024x600Data_2; + SiS_Pr->SiS_LVDS1152x768Data_1 = SiS_LVDS1152x768Data_1; + SiS_Pr->SiS_LVDS1152x768Data_2 = SiS_LVDS1152x768Data_2; + SiS_Pr->SiS_LVDSXXXxXXXData_1 = SiS_LVDSXXXxXXXData_1; + SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x960Data_1; + SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x960Data_2; + SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1; + SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x1024Data_1; + SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x1024Data_2; + SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1; + SiS_Pr->SiS_LVDS640x480Data_2 = SiS_LVDS640x480Data_2; + + SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1; + SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2; + SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1; + SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2; + SiS_Pr->SiS_LVDS848x480Data_1 = SiS_LVDS848x480Data_1; + SiS_Pr->SiS_LVDS848x480Data_2 = SiS_LVDS848x480Data_2; + + SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1; + SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2; + SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1; + SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2; + SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData; + SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData; + + SiS_Pr->LVDS1024x768Des_1 = SiS_PanelType1076_1; + SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1; + SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1; + SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1; + SiS_Pr->LVDS1024x768Des_2 = SiS_PanelType1076_2; + SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2; + SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2; + SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2; + + SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1; + SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2; + + SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData; + SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData; + SiS_Pr->SiS_CHTVUPALDesData = SiS_CHTVUPALDesData; + SiS_Pr->SiS_CHTVOPALDesData = SiS_CHTVOPALDesData; + + SiS_Pr->SiS_LVDSCRT11280x768_1 = SiS_LVDSCRT11280x768_1; + SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1; + SiS_Pr->SiS_LVDSCRT11152x768_1 = SiS_LVDSCRT11152x768_1; + SiS_Pr->SiS_LVDSCRT11280x768_1_H = SiS_LVDSCRT11280x768_1_H; + SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H; + SiS_Pr->SiS_LVDSCRT11152x768_1_H = SiS_LVDSCRT11152x768_1_H; + SiS_Pr->SiS_LVDSCRT11280x768_2 = SiS_LVDSCRT11280x768_2; + SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2; + SiS_Pr->SiS_LVDSCRT11152x768_2 = SiS_LVDSCRT11152x768_2; + SiS_Pr->SiS_LVDSCRT11280x768_2_H = SiS_LVDSCRT11280x768_2_H; + SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H; + SiS_Pr->SiS_LVDSCRT11152x768_2_H = SiS_LVDSCRT11152x768_2_H; + SiS_Pr->SiS_LVDSCRT1320x480_1 = SiS_LVDSCRT1320x480_1; + SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS_LVDSCRT1XXXxXXX_1; + SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS_LVDSCRT1XXXxXXX_1_H; + SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1; + SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H; + SiS_Pr->SiS_LVDSCRT1640x480_2 = SiS_LVDSCRT1640x480_2; + SiS_Pr->SiS_LVDSCRT1640x480_2_H = SiS_LVDSCRT1640x480_2_H; + SiS_Pr->SiS_LVDSCRT1640x480_3 = SiS_LVDSCRT1640x480_3; + SiS_Pr->SiS_LVDSCRT1640x480_3_H = SiS_LVDSCRT1640x480_3_H; } #ifdef SIS300 static void InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) { + InitCommonPointer(SiS_Pr, HwDeviceExtension); + SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS300_SModeIDTable; SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable; - SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS300_StandTable; SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS300_EModeIDTable; SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS300_RefIndex; SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS300_CRT1Table; if(HwDeviceExtension->jChipType == SIS_300) { SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */ } else { - SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630 */ + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */ } +#ifdef LINUXBIOS SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS300_ECLKData; +#endif SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS300_VCLKData; SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData; SiS_Pr->SiS_ScreenOffset = SiS300_ScreenOffset; - SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS300_StResInfo; - SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo; - - SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect; - SiS_Pr->pSiS_SoftSetting = &SiS300_SoftSetting; SiS_Pr->SiS_SR15 = SiS300_SR15; @@ -207,15 +320,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->pSiS_YCSenseData2 = &SiS300_YCSenseData2; #endif - SiS_Pr->SiS_NTSCPhase = SiS300_NTSCPhase; - SiS_Pr->SiS_PALPhase = SiS300_PALPhase; - SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2; - SiS_Pr->SiS_PALPhase2 = SiS300_PALPhase2; - SiS_Pr->SiS_PALMPhase = SiS300_PALMPhase; - SiS_Pr->SiS_PALNPhase = SiS300_PALNPhase; - SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2; - SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2; - SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data; SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data; SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data; @@ -224,70 +328,18 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data; SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768; SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024; - SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data; - SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data; - SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data; - SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data; - SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data; - SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050; - SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200; - - SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS300_StPALData; - SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS300_ExtPALData; - SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS300_StNTSCData; - SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData; -#ifdef oldHV - SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData; - SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData; - SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData; -#endif - - SiS_Pr->SiS_NTSCTiming = SiS300_NTSCTiming; - SiS_Pr->SiS_PALTiming = SiS300_PALTiming; -#ifdef oldHV - SiS_Pr->SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing; - SiS_Pr->SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing; - SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming; - SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data; - SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu; - SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text; -#endif SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl; SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS; - SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1; - SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2; - SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1; - SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2; - SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1; - SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2; - SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1; - SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2; - SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1; - SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2; - SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1; - SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2; - SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1; - SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2; - SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1; - SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2; - SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1; - SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1; - SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1; - SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1; - SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2; - SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1; - SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2; - SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; - SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData; SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData; - SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */ - SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */ SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData; /* not supported on 300 series */ SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData; /* not supported on 300 series */ SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData; + SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1; SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1; SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1; @@ -320,30 +372,28 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2; SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2; SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2; - SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData; - SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData; - SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData; - SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData; + + if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { + SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a; + SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a; + } + if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { + SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b; + SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b; + } + SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1; SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1; SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1; - SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1; - SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1; SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H; SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H; SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H; - SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H; - SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H; SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2; SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2; SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2; - SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2; - SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2; SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H; SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H; SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H; - SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H; - SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H; SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC; SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC; SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL; @@ -368,7 +418,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */ SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL; - /* TW: New from 300/301LV BIOS */ SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1; SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1; SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1; @@ -382,7 +431,7 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3; SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3; - /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */ + /* TW: LCDResInfo will on 300 series be translated to 315 series definitions */ SiS_Pr->SiS_Panel320x480 = Panel_320x480; SiS_Pr->SiS_Panel640x480 = Panel_640x480; SiS_Pr->SiS_Panel800x600 = Panel_800x600; @@ -391,13 +440,17 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_Panel1280x960 = Panel_1280x960; SiS_Pr->SiS_Panel1024x600 = Panel_1024x600; SiS_Pr->SiS_Panel1152x768 = Panel_1152x768; - SiS_Pr->SiS_Panel1600x1200 = 16; /* TW: Something illegal */ - SiS_Pr->SiS_Panel1400x1050 = 16; /* TW: Something illegal */ - SiS_Pr->SiS_Panel1152x864 = 16; /* TW: Something illegal */ - SiS_Pr->SiS_Panel1280x768 = 16; /* TW: Something illegal */ + SiS_Pr->SiS_Panel1280x768 = Panel_1280x768; + SiS_Pr->SiS_Panel1600x1200 = 255; /* TW: Something illegal */ + SiS_Pr->SiS_Panel1400x1050 = 255; /* TW: Something illegal */ + SiS_Pr->SiS_Panel640x480_2 = 255; /* TW: Something illegal */ + SiS_Pr->SiS_Panel640x480_3 = 255; /* TW: Something illegal */ + SiS_Pr->SiS_Panel1152x864 = 255; /* TW: Something illegal */ SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */ SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: Lowest value LVDS */ SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */ + SiS_Pr->SiS_PanelCustom = Panel_Custom; + SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366; } #endif @@ -405,29 +458,33 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) static void InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) { + InitCommonPointer(SiS_Pr, HwDeviceExtension); + SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS310_SModeIDTable; - SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS310_StandTable; SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS310_EModeIDTable; SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex; SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS310_CRT1Table; /* TW: MCLK is different */ - if(HwDeviceExtension->jChipType == SIS_330) { +#ifdef LINUXBIOS + if(HwDeviceExtension->jChipType >= SIS_660) { + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660; /* 660/760 */ + } else if(HwDeviceExtension->jChipType == SIS_330) { +#endif SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330; /* 330 */ +#ifdef LINUXBIOS } else if(HwDeviceExtension->jChipType > SIS_315PRO) { - SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650; /* 550, 650 */ + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650; /* 550, 650, 740 */ } else { SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315; /* 315 */ } +#endif SiS_Pr->SiS_MCLKData_1 = (SiS_MCLKDataStruct *)SiS310_MCLKData_1; +#ifdef LINUXBIOS SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS310_ECLKData; +#endif SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS310_VCLKData; SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData; SiS_Pr->SiS_ScreenOffset = SiS310_ScreenOffset; - SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS310_StResInfo; - SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo; - - SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect; - SiS_Pr->pSiS_SoftSetting = &SiS310_SoftSetting; SiS_Pr->SiS_SR15 = SiS310_SR15; @@ -456,16 +513,6 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->pSiS_YCSenseData2 = &SiS310_YCSenseData2; #endif - SiS_Pr->SiS_NTSCPhase = SiS310_NTSCPhase; - SiS_Pr->SiS_PALPhase = SiS310_PALPhase; - SiS_Pr->SiS_NTSCPhase2 = SiS310_NTSCPhase2; - SiS_Pr->SiS_PALPhase2 = SiS310_PALPhase2; - SiS_Pr->SiS_PALMPhase = SiS310_PALMPhase; - SiS_Pr->SiS_PALNPhase = SiS310_PALNPhase; - SiS_Pr->SiS_PALMPhase2 = SiS310_PALMPhase2; - SiS_Pr->SiS_PALNPhase2 = SiS310_PALNPhase2; - SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase; - SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data; SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data; SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data; @@ -474,64 +521,10 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data; SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768; SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024; - SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data; - SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data; - SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data; - SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data; - SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data; - SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050; - SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200; - - SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS310_StPALData; - SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS310_ExtPALData; - SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS310_StNTSCData; - SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData; -#ifdef oldHV - SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData; - SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData; - SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData; -#endif - SiS_Pr->SiS_NTSCTiming = SiS310_NTSCTiming; - SiS_Pr->SiS_PALTiming = SiS310_PALTiming; -#ifdef oldHV - SiS_Pr->SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing; - SiS_Pr->SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing; - SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming; - SiS_Pr->SiS_HiTVExtTiming = SiS310_HiTVExtTiming; - SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data; - SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu; - SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text; -#endif - - SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl; + SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl; SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS; - SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1; - SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2; - SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1; - SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2; - SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1; - SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2; - SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1; - SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2; - SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1; - SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2; - SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1; - SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2; - SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1; - SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2; - SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1; - SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2; - SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1; - SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1; - SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1; - SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1; - SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2; - SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1; - SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2; - SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData; - SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData; SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData; SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData; SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData; @@ -539,6 +532,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData; SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData; SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData; + SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1; SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1; SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1; @@ -572,16 +566,6 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2; SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2; - SiS_Pr->LVDS1024x768Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1; - SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1; - SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ; - SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ; - SiS_Pr->LVDS1024x768Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2; - SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2; - SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2; - SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ; - - /* TW: New from 650/301LV BIOS */ SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1; SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1; SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1; @@ -595,50 +579,32 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3; SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3; - SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData; - SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData; - SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData; - SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData; - SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1; SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1; SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1; SiS_Pr->SiS_LVDSCRT11400x1050_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1; - SiS_Pr->SiS_LVDSCRT11280x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1; - SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1; - SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1; SiS_Pr->SiS_LVDSCRT11600x1200_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1; SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H; SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H; SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H; SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H; - SiS_Pr->SiS_LVDSCRT11280x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H; - SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H; - SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H; SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H; SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2; SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2; SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2; SiS_Pr->SiS_LVDSCRT11400x1050_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2; - SiS_Pr->SiS_LVDSCRT11280x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2; - SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2; - SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2; SiS_Pr->SiS_LVDSCRT11600x1200_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2; SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H; SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H; SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H; SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H; - SiS_Pr->SiS_LVDSCRT11280x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H; - SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H; - SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H; SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H; - SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1; - SiS_Pr->SiS_LVDSCRT1320x480_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1; - SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC; - SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC; - SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL; - SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL; - SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL; + SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC; + SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC; + SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL; + SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL; + SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL; + SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC; SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC; SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL; @@ -648,6 +614,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN; SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN; SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL; + SiS_Pr->SiS_LCDACRT1800x600_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1; SiS_Pr->SiS_LCDACRT11024x768_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1; SiS_Pr->SiS_LCDACRT11280x1024_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1; @@ -668,6 +635,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H; SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H; SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H; + SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC; SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC; SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL; @@ -690,9 +658,13 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_Pr->SiS_Panel1152x864 = Panel_1152x864; SiS_Pr->SiS_Panel1280x768 = Panel_1280x768; SiS_Pr->SiS_Panel1024x600 = Panel_1024x600; + SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2; + SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3; SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */ SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: lowest value LVDS/LCDA */ SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */ + SiS_Pr->SiS_PanelCustom = Panel_Custom; + SiS_Pr->SiS_PanelBarco1366 = 255; } #endif @@ -702,7 +674,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) * don't need this otherwise. Under normal * circumstances, the video BIOS has initialized * the adapter for us. BTW, this code is incomplete - * and very possibly not functioning on newer chipsets. + * and very possibly not working on newer chipsets. */ BOOLEAN SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) @@ -755,7 +727,9 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) (HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_650) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_330)) + (HwDeviceExtension->jChipType == SIS_330) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) InitTo310Pointer(SiS_Pr, HwDeviceExtension); #endif @@ -924,7 +898,9 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) (HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_650) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_330)) { + (HwDeviceExtension->jChipType == SIS_330) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) { for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0); for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0); } @@ -981,14 +957,16 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) if((HwDeviceExtension->jChipType == SIS_315H) || (HwDeviceExtension->jChipType == SIS_315) || (HwDeviceExtension->jChipType == SIS_315PRO) || - (HwDeviceExtension->jChipType == SIS_330) ) { + (HwDeviceExtension->jChipType == SIS_330)) { if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) { temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03; } } if((HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_650)) { + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) { if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) { temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07; } @@ -1005,7 +983,7 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) if((HwDeviceExtension->jChipType != SIS_540) && (HwDeviceExtension->jChipType != SIS_630) && (HwDeviceExtension->jChipType != SIS_730)){ - for(i=0x15;i<0x1C;i++) { + for(i=0x15; i<0x1C; i++) { SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]); } } @@ -1051,7 +1029,9 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) (HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_650) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_330)) + (HwDeviceExtension->jChipType == SIS_330) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08); /* use VB */ #endif @@ -1208,7 +1188,9 @@ SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension #ifdef SIS315H if((HwDeviceExtension->jChipType == SIS_650) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_330)) { + (HwDeviceExtension->jChipType == SIS_330) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) { #if 0 /* TW: This is not required */ /* TW: Read POWER_ON_TRAP and copy to CR37 */ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A); @@ -1327,7 +1309,7 @@ SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress) #endif /* =============== SiS 300 dram sizing end =============== */ -/* ============ SiS 310/325 dram sizing begin ============== */ +/* ============ SiS 315 dram sizing begin ============== */ #ifdef SIS315H /* TW: Moved Get310DRAMType further down */ @@ -1921,8 +1903,7 @@ SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDev if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) { data = *SiS_Pr->pSiS_SoftSetting & 0x03; } else { - if((HwDeviceExtension->jChipType > SIS_315PRO) && - (HwDeviceExtension->jChipType < SIS_330)) { + if(IS_SIS550650740660) { data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07; } else { /* TW: 315, 330 */ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03; @@ -1962,13 +1943,17 @@ void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr) SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; - SiS_Pr->SiS_P3da = BaseAddr + 0x2A; - SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */ - SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */ - SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */ - SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */ - SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */ - SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */ + SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; + SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; + SiS_Pr->SiS_P3da = BaseAddr + 0x2a; + SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */ + SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */ + SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */ + SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */ + SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */ + SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */ + SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE; + SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK; } void @@ -1993,7 +1978,9 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) (HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_650) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_330)) { + (HwDeviceExtension->jChipType == SIS_330) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) { /* TW: This seems to be done the same way on these chipsets */ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1); SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A); @@ -2015,10 +2002,14 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT SiS_Pr->SiS_ChrontelInit = 0; - if((ModeNo == 0x5a) || (ModeNo == 0x5b)) { - SiS_Pr->SiS_IF_DEF_DSTN = 1; /* for 550 dstn */ - SiS_Pr->SiS_IF_DEF_FSTN = 1; /* for fstn */ +#if 0 + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((ModeNo == 0x5a) || (ModeNo == 0x5b)) { + SiS_Pr->SiS_IF_DEF_DSTN = 1; /* for 550 dstn */ + SiS_Pr->SiS_IF_DEF_FSTN = 1; /* for fstn */ + } } +#endif #ifdef SIS300 if((HwDeviceExtension->jChipType == SIS_540) || @@ -2043,11 +2034,15 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT if((HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_650) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_330)) + (HwDeviceExtension->jChipType == SIS_330) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) { - /* TW: CR37 is different on 310/325 series */ + /* TW: CR37 is different on 315 series */ +#if 0 if(SiS_Pr->SiS_IF_DEF_FSTN) /* fstn: set CR37=0x04 */ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04); /* (fake LVDS bridge) */ +#endif temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37); temp = (temp & 0x0E) >> 1; @@ -2072,7 +2067,9 @@ SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) (HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_650) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_330)) + (HwDeviceExtension->jChipType == SIS_330) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) InitTo310Pointer(SiS_Pr, HwDeviceExtension); #endif @@ -2101,14 +2098,21 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, SiS_Pr->SiS_UseROM = TRUE; else SiS_Pr->SiS_UseROM = FALSE; } else if(HwDeviceExtension->jChipType < SIS_315H) { +#if 0 /* TW: Rest of 300 series: We don't use the ROM image if * the BIOS version < 2.0.0 as such old BIOSes don't * have the needed data at the expected locations. */ if(ROMAddr[0x06] < '2') SiS_Pr->SiS_UseROM = FALSE; else SiS_Pr->SiS_UseROM = TRUE; +#else + /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps + * the others do as well + */ + SiS_Pr->SiS_UseROM = TRUE; +#endif } else { - /* TW: 310/325/330 series stick to the standard */ + /* TW: 315/330 series stick to the standard */ SiS_Pr->SiS_UseROM = TRUE; } } else SiS_Pr->SiS_UseROM = FALSE; @@ -2132,24 +2136,27 @@ SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnI SiS_Pr->UseCustomMode = FALSE; if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", - SiS_Pr->CHDisplay, SiS_Pr->CVDisplay); - + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", + SiS_Pr->CHDisplay, + (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 : + (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 : + SiS_Pr->CVDisplay))); + return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE)); - + } - - ModeNo = SiS_CalcModeIndex(pScrn, mode); + + ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes); if(!ModeNo) return FALSE; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo); - return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE)); + return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE)); } #ifdef SISDUALHEAD -/* TW: Set CRT1 mode (used for dual head) */ +/* TW: Set CRT1 mode (used for dual head and MergedFB) */ BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom) @@ -2162,31 +2169,37 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S SISEntPtr pSiSEnt = pSiS->entityPrivate; unsigned char backupreg=0; BOOLEAN backupcustom; - UShort ModeNo=0; SiS_Pr->UseCustomMode = FALSE; - + if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { - + + USHORT temptemp = SiS_Pr->CVDisplay; + + if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; + else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting custom mode %dx%d in CRT1\n", - SiS_Pr->CHDisplay, SiS_Pr->CVDisplay); + "Setting custom mode %dx%d on CRT1\n", + SiS_Pr->CHDisplay, temptemp); ModeNo = 0xfe; - + } else { - ModeNo = SiS_CalcModeIndex(pScrn, mode); + ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes); if(!ModeNo) return FALSE; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting mode 0x%x on CRT1\n", ModeNo); + "Setting standard mode 0x%x on CRT1\n", ModeNo); } SiSInitPtr(SiS_Pr, HwDeviceExtension); SiSRegInit(SiS_Pr, BaseAddr); + SiS_GetSysFlags(SiS_Pr, HwDeviceExtension); + SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); SiSInitPCIetc(SiS_Pr, HwDeviceExtension); @@ -2195,7 +2208,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr); - /* TW: We don't clear the buffer under X */ + /* We don't clear the buffer under X */ SiS_Pr->SiS_flag_clearbuffer = 0; /* 1.Openkey */ @@ -2203,8 +2216,8 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); + /* 2.Get ModeID Table */ if(!SiS_Pr->UseCustomMode) { - /* 2.Get ModeID Table */ temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex); if(temp == 0) return(0); } else { @@ -2222,62 +2235,72 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S } } - SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension); - /* TW: Get VB information (connectors, connected devices) */ /* (We don't care if the current mode is a CRT2 mode) */ SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0); + SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension); SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); if(HwDeviceExtension->jChipType >= SIS_315H) { if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) { - /* TW: I am not sure the flag's name is correct */ - if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode; + } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) { + SiS_Pr->SiS_SetFlag |= SetDOSMode; + } } - /* TW: New from 650/LV 1.10.6x */ - if(IS_SIS650740) { - if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { - SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); - SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); - } + if(IS_SIS650) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); + if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20); + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); + } } } - /* TW: Set mode on CRT1 */ + /* Set mode on CRT1 */ SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr); - pSiSEnt->CRT1ModeNo = ModeNo; - pSiSEnt->CRT1DMode = mode; - - /* TW: SetPitch: Adapt to virtual size & position */ + /* SetPitch: Adapt to virtual size & position */ SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr); - /* We have to reset CRT2 if changing mode on CRT1 */ - if(pSiSEnt->CRT2ModeNo != -1) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "(Re-)Setting mode 0x%x on CRT2\n", - pSiSEnt->CRT2ModeNo); - backupcustom = SiS_Pr->UseCustomMode; - if(SiS_Pr->UseCustomMode) { - SiS_Pr->CRT1UsesCustomMode = TRUE; - } else { - SiS_Pr->CRT1UsesCustomMode = FALSE; - } - SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1, - pSiSEnt->CRT2DMode); - SiS_Pr->UseCustomMode = backupcustom; - SiS_Pr->CRT1UsesCustomMode = FALSE; + if(pSiS->DualHeadMode) { + pSiSEnt->CRT1ModeNo = ModeNo; + pSiSEnt->CRT1DMode = mode; } - if(IS_SIS650740) { /* TW: *** For 650 only! *** */ - SiS_HandleCRT1(SiS_Pr); + if(SiS_Pr->UseCustomMode) { + SiS_Pr->CRT1UsesCustomMode = TRUE; + SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock; + SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag; + } else { + SiS_Pr->CRT1UsesCustomMode = FALSE; } + /* We have to reset CRT2 if changing mode on CRT1 */ + if(pSiS->DualHeadMode) { + if(pSiSEnt->CRT2ModeNo != -1) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "(Re-)Setting mode for CRT2\n"); + backupcustom = SiS_Pr->UseCustomMode; + SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1, + pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom); + SiS_Pr->UseCustomMode = backupcustom; + } + } + + /* Warning: From here, the custom mode entries in SiS_Pr are + * possibly overwritten + */ + + SiS_HandleCRT1(SiS_Pr); + + SiS_StrangeStuff(SiS_Pr, HwDeviceExtension); + SiS_DisplayOn(SiS_Pr); SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF); - /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { if(HwDeviceExtension->jChipType >= SIS_315H) { SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg); @@ -2296,7 +2319,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S /* TW: Set CRT2 mode (used for dual head) */ BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, - DisplayModePtr mode) + DisplayModePtr mode, BOOLEAN IsCustom) { ULONG temp; USHORT ModeIdIndex; @@ -2306,16 +2329,52 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S SISPtr pSiS = SISPTR(pScrn); SISEntPtr pSiSEnt = pSiS->entityPrivate; unsigned char tempr1, tempr2, backupreg=0; - + SiS_Pr->UseCustomMode = FALSE; - - ModeNo = SiS_CalcModeIndex(pScrn, mode); - if(!ModeNo) return FALSE; + + /* Remember: Custom modes for CRT2 are ONLY supported + * -) on 315/330 series, + * -) on the 301 and 30xB, and + * -) if CRT2 is LCD or VGA + */ + + if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { + + ModeNo = 0xfe; + + } else { + + BOOLEAN havecustommodes = pSiS->HaveCustomModes; + +#ifdef SISMERGED + if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2; +#endif + + ModeNo = SiS_CalcModeIndex(pScrn, mode, havecustommodes); + if(!ModeNo) return FALSE; + + } + + /* Save mode info so we can set it from within SetMode for CRT1 */ + if(pSiS->DualHeadMode) { + pSiSEnt->CRT2ModeNo = ModeNo; + pSiSEnt->CRT2DMode = mode; + pSiSEnt->CRT2IsCustom = IsCustom; + + /* We can't set CRT2 mode before CRT1 mode is set */ + if(pSiSEnt->CRT1ModeNo == -1) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Setting CRT2 mode delayed until after setting CRT1 mode\n"); + return TRUE; + } + } SiSInitPtr(SiS_Pr, HwDeviceExtension); SiSRegInit(SiS_Pr, BaseAddr); + SiS_GetSysFlags(SiS_Pr, HwDeviceExtension); + SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); SiSInitPCIetc(SiS_Pr, HwDeviceExtension); @@ -2324,22 +2383,26 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr); - /* TW: We don't clear the buffer under X */ + /* We don't clear the buffer under X */ SiS_Pr->SiS_flag_clearbuffer=0; - /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */ - pSiSEnt->CRT2ModeNo = ModeNo; - pSiSEnt->CRT2DMode = mode; + if(SiS_Pr->UseCustomMode) { - /* TW: We can't set CRT2 mode before CRT1 mode is set */ - if(pSiSEnt->CRT1ModeNo == -1) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting CRT2 mode delayed until after setting CRT1 mode\n"); - return TRUE; - } + USHORT temptemp = SiS_Pr->CVDisplay; + + if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; + else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Setting custom mode %dx%d on CRT2\n", + SiS_Pr->CHDisplay, temptemp); + + } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting mode 0x%x on CRT2\n", ModeNo); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Setting standard mode 0x%x on CRT2\n", ModeNo); + + } /* 1.Openkey */ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); @@ -2347,10 +2410,14 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); /* 2.Get ModeID */ - temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex); - if(temp == 0) return(0); + if(!SiS_Pr->UseCustomMode) { + temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex); + if(temp == 0) return(0); + } else { + ModeIdIndex = 0; + } - /* TW: Determine VBType (301,301B,301LV,302B,302LV) */ + /* Determine VBType (301,301B,301LV,302B,302LV) */ SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension); if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { @@ -2373,15 +2440,23 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S } } - /* TW: Get VB information (connectors, connected devices) */ + /* Get VB information (connectors, connected devices) */ + if(!SiS_Pr->UseCustomMode) { + SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1); + } else { + /* If this is a custom mode, we don't check the modeflag for CRT2Mode */ + SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0); + } SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension); - SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1); SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); if(HwDeviceExtension->jChipType >= SIS_315H) { if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) { - /* TW: I am not sure the flag's name is correct */ - if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode; + } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) { + SiS_Pr->SiS_SetFlag |= SetDOSMode; + } } } @@ -2390,24 +2465,22 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S case VB_CHIP_301: case VB_CHIP_301B: case VB_CHIP_301LV: - case VB_CHIP_301LVX: case VB_CHIP_302: case VB_CHIP_302B: case VB_CHIP_302LV: - case VB_CHIP_302LVX: - SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); - break; - case VB_CHIP_303: + SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); break; case VB_CHIP_UNKNOWN: - if (SiS_Pr->SiS_IF_DEF_LVDS == 1 || - SiS_Pr->SiS_IF_DEF_CH70xx != 0 || - SiS_Pr->SiS_IF_DEF_TRUMPION != 0) { - SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); + if(SiS_Pr->SiS_IF_DEF_LVDS == 1 || + SiS_Pr->SiS_IF_DEF_CH70xx != 0 || + SiS_Pr->SiS_IF_DEF_TRUMPION != 0) { + SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); } break; } + SiS_StrangeStuff(SiS_Pr, HwDeviceExtension); + SiS_DisplayOn(SiS_Pr); SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF); @@ -2419,7 +2492,6 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S } } - /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { if(HwDeviceExtension->jChipType >= SIS_315H) { if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { @@ -2445,7 +2517,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, S } } - /* TW: SetPitch: Adapt to virtual size & position */ + /* SetPitch: Adapt to virtual size & position */ SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr); return TRUE; @@ -2475,18 +2547,26 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod if(SiS_Pr->UseCustomMode) { ModeNo = 0xfe; - } - + } + SiSInitPtr(SiS_Pr, HwDeviceExtension); SiSRegInit(SiS_Pr, BaseAddr); + SiS_GetSysFlags(SiS_Pr, HwDeviceExtension); + #ifdef LINUX_XF86 if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); else #endif SiS_Pr->SiS_VGAINFO = 0x11; +#ifdef LINUX_XF86 +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO); +#endif +#endif + SiSInitPCIetc(SiS_Pr, HwDeviceExtension); SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo); @@ -2496,10 +2576,10 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod if(!SiS_Pr->UseCustomMode) { /* TW: Shift the clear-buffer-bit away */ ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f); - } + } #ifdef LINUX_XF86 - /* TW: We never clear the buffer in X */ + /* We never clear the buffer in X */ ModeNo |= 0x8000; #endif @@ -2517,21 +2597,21 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); if(!SiS_Pr->UseCustomMode) { - + /* 2.Get ModeID Table */ temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex); if(temp == 0) return(0); - + } else { - + ModeIdIndex = 0; - + } - - /* TW: Determine VBType (301,301B,301LV,302B,302LV) */ + + /* Determine VBType (301,301B,301LV,302B,302LV) */ SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension); - /* TW: Init/restore some VB registers */ + /* Init/restore some VB registers */ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { if(HwDeviceExtension->jChipType >= SIS_315H) { SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr); @@ -2552,9 +2632,13 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod } } - /* TW: Get VB information (connectors, connected devices) */ + /* Get VB information (connectors, connected devices) */ + if(SiS_Pr->UseCustomMode) { + SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0); + } else { + SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1); + } SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension); - SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1); SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); /* 3. Check memory size */ @@ -2563,20 +2647,31 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod if(HwDeviceExtension->jChipType >= SIS_315H) { if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) { - /* TW: I am not sure the flag's name is correct */ - if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode; + } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) { + SiS_Pr->SiS_SetFlag |= SetDOSMode; + } } - /* TW: New from 650/LV 1.10.6x */ - if(IS_SIS650740) { - if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { - SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); - SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); - } + if(IS_SIS650) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); + if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20); + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); + } } } - /* TW: Set mode on CRT1 */ + if(SiS_Pr->UseCustomMode) { + SiS_Pr->CRT1UsesCustomMode = TRUE; + SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock; + SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag; + } else { + SiS_Pr->CRT1UsesCustomMode = FALSE; + } + + /* Set mode on CRT1 */ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) { SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr); } else { @@ -2585,45 +2680,34 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod } } - /* TW: Set mode on CRT2 */ + /* Set mode on CRT2 */ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) { switch (HwDeviceExtension->ujVBChipID) { case VB_CHIP_301: case VB_CHIP_301B: case VB_CHIP_301LV: - case VB_CHIP_301LVX: case VB_CHIP_302: case VB_CHIP_302B: case VB_CHIP_302LV: - case VB_CHIP_302LVX: - SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); - break; - case VB_CHIP_303: + SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); break; case VB_CHIP_UNKNOWN: if(SiS_Pr->SiS_IF_DEF_LVDS == 1 || SiS_Pr->SiS_IF_DEF_CH70xx != 0 || SiS_Pr->SiS_IF_DEF_TRUMPION != 0) - SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); + SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); break; } } + + SiS_HandleCRT1(SiS_Pr); - if(IS_SIS650740) { /* TW: For 650 only! */ - SiS_HandleCRT1(SiS_Pr); - } - + SiS_StrangeStuff(SiS_Pr, HwDeviceExtension); + SiS_DisplayOn(SiS_Pr); SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF); if(HwDeviceExtension->jChipType >= SIS_315H) { -#if 0 - if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { - if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { - SiS_Handle301B_1400x1050(SiS_Pr, ModeNo); - } - } -#endif if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) { SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); @@ -2631,7 +2715,6 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod } } - /* TW: New from 650/LV 1.10.6x and 1.10.7w */ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { if(HwDeviceExtension->jChipType >= SIS_315H) { if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { @@ -2648,17 +2731,15 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB; SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2); - if((IS_SIS650740) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) { - if((ModeNo == 0x03) || (ModeNo == 0x10)) { - SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80); - SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08); - } + if((IS_SIS650) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) { + if((ModeNo == 0x03) || (ModeNo == 0x10)) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80); + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08); + } } if(tempr1 & SetCRT2ToLCD) { -/* if(ModeNo <= 0x13) { - not in 1.10.8r */ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); -/* } */ } } else if((HwDeviceExtension->jChipType == SIS_630) || (HwDeviceExtension->jChipType == SIS_730)) { @@ -2668,7 +2749,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod #ifdef LINUX_XF86 if(pScrn) { - /* TW: SetPitch: Adapt to virtual size & position */ + /* SetPitch: Adapt to virtual size & position */ if((ModeNo > 0x13) && (dosetpitch)) { SiS_SetPitch(SiS_Pr, pScrn, BaseAddr); } @@ -2678,7 +2759,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod } #endif -#ifndef LINUX_XF86 /* TW: We never lock registers in XF86 */ +#ifndef LINUX_XF86 /* We never lock registers in XF86 */ if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00); #endif @@ -2687,44 +2768,93 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT Mod } void -SiS_SetEnableDstn(SiS_Private *SiS_Pr) /* TW: Called from sis_main.c */ +SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable) { - /* For 550 dstn */ - SiS_Pr->SiS_IF_DEF_DSTN = 1; + SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0; } void -SiS_HandleCRT1(SiS_Private *SiS_Pr) +SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable) { - /* TW: Do this on 650 only! */ + SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0; +} - /* TW: No, we don't do this at all. There is a new - * CRT1-is-connected-at-boot-time logic in the 650, which +void +SiS_HandleCRT1(SiS_Private *SiS_Pr) +{ + /* TW: We don't do this at all. There is a new + * CRT1-is-connected-at-boot-time logic in the 650 BIOS, which * confuses our own. So just clear the bit and skip the rest. */ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf); #if 0 - if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) - SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40); + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) { + if((SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x0a) || + (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x01)) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40); + } } #endif } -#if 0 void -SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo) +SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) { - if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { - if(ModeNo <= 0x13) { - if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (SetNotSimuMode >> 8)) { - SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xFC); - } - } - } + unsigned char cr5f, temp1, temp2; + + /* You should use the macros, not these flags directly */ + + SiS_Pr->SiS_SysFlags = 0; + if(HwDeviceExtension->jChipType == SIS_650) { + cr5f = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0; + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07); + temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8); + temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; + if((!temp1) || (temp2)) { + switch(cr5f) { + case 0x80: + case 0x90: + case 0xc0: + SiS_Pr->SiS_SysFlags |= SF_IsM650; break; + case 0xa0: + case 0xb0: + case 0xe0: + SiS_Pr->SiS_SysFlags |= SF_Is651; break; + } + } else { + switch(cr5f) { + case 0x90: + temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; + switch(temp1) { + case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break; + case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break; + default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break; + } + break; + case 0xb0: + SiS_Pr->SiS_SysFlags |= SF_Is652; break; + default: + SiS_Pr->SiS_SysFlags |= SF_IsM650; break; + } + } + } +} + +void +SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + if((IS_SIS651) || (IS_SISM650)) { + SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */ + SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x00, 0x00); + SiS_SetReg1(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */ + SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */ + SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef); + } + /* !!! This does not support modes < 0x13 !!! */ } -#endif void SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, @@ -2740,6 +2870,9 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDevic } } + /* 550, 651 */ + SiS_WhatTheHellIsThis(SiS_Pr,HwDeviceExtension,BaseAddr); + SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex); SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex); SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex); @@ -2816,15 +2949,20 @@ void SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr) { SISPtr pSiS = SISPTR(pScrn); + BOOLEAN isslavemode = FALSE; + + if( (pSiS->VBFlags & VB_VIDEOBRIDGE) && + ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) || + ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) { + isslavemode = TRUE; + } - /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */ - if( (pSiS->VBFlags & DISPTYPE_DISP1) || - ( (pSiS->VBFlags & VB_VIDEOBRIDGE) && - ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) || - ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) { + /* We need to set pitch for CRT1 if bridge is in slave mode, too */ + if( (pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode) ) { SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr); } - if (pSiS->VBFlags & DISPTYPE_DISP2) { + /* We must not set the pitch for CRT2 if bridge is in slave mode */ + if( (pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode) ) { SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr); } } @@ -2847,7 +2985,7 @@ SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr) SISPtr pSiS = SISPTR(pScrn); ULong HDisplay,temp; - HDisplay = pSiS->scrnPitch / 8; + HDisplay = pSiS->scrnPitch2 / 8; /* Unlock CRT2 */ if (pSiS->VGAEngine == SIS_315_VGA) @@ -2861,8 +2999,6 @@ SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr) } #endif -/* TW: Checked against 650/301 and 630/301B BIOS */ -/* TW: Re-written for 650/301LVx 1.10.6s BIOS */ void SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) { @@ -2875,7 +3011,7 @@ SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceE flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00); /* TW: Illegal values not welcome... */ - if(flag > 10) return; + if(flag > 3) return; rev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01); @@ -2885,29 +3021,24 @@ SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceE SiS_Pr->SiS_VBType = VB_SIS301; if(rev >= 0xB0) { SiS_Pr->SiS_VBType = VB_SIS301B; - if((HwDeviceExtension->jChipType >= SIS_315H) || - (HwDeviceExtension->jChipType == SIS_300)) { - /* 650/301LV and 300/301LV use this, 630/301B does not */ - nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23); - if(!(nolcd & 0x02)) - SiS_Pr->SiS_VBType |= VB_NoLCD; - } + /* Check if 30xB DH version (no LCD support, use Panel Link instead) */ + nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23); + if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD; } } if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) { if(rev >= 0xD0) { SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS302B); - SiS_Pr->SiS_VBType |= VB_SIS30xLV; + SiS_Pr->SiS_VBType |= VB_SIS301LV; SiS_Pr->SiS_VBType &= ~(VB_NoLCD); if(rev >= 0xE0) { - SiS_Pr->SiS_VBType &= ~(VB_SIS30xLV); - SiS_Pr->SiS_VBType |= VB_SIS30xNEW; + SiS_Pr->SiS_VBType &= ~(VB_SIS301LV); + SiS_Pr->SiS_VBType |= VB_SIS302LV; } } } } -/* TW: Checked against 650/301LVx 1.10.6s */ BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex) { @@ -2915,9 +3046,9 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *Mode if(*ModeNo <= 0x13) { - if((*ModeNo) <= 5) (*ModeNo) |= 1; + if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01; - for(*ModeIdIndex=0;;(*ModeIdIndex)++) { + for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break; if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF) return FALSE; } @@ -2926,7 +3057,7 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *Mode if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ /* else 350 lines */ } - if(*ModeNo <= 3) { + if(*ModeNo <= 0x03) { if(!(VGAINFO & 0x80)) (*ModeIdIndex)++; if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ /* else 350 lines */ @@ -2935,7 +3066,7 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *Mode } else { - for(*ModeIdIndex=0;;(*ModeIdIndex)++) { + for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break; if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return FALSE; } @@ -2944,7 +3075,6 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *Mode return TRUE; } -/* For SiS 300 oem util: Search VBModeID */ BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo) { @@ -2968,7 +3098,6 @@ SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo) return ((BOOLEAN)ModeIdIndex); } -/* TW: Checked against 630/301B, 315 1.09 and 650/301LVx 1.10.6s BIOS */ BOOLEAN SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,USHORT ModeIdIndex) @@ -3011,7 +3140,81 @@ SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIn return index; } -/* TW: Checked against 300, 330, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */ +static void +SiS_WhatIsThis1a(SiS_Private *SiS_Pr, USHORT somevalue) +{ + USHORT temp, tempbl, tempbh; + + tempbl = tempbh = somevalue; + temp = SiS_GetReg2(SiS_Pr->SiS_P3cb); + temp &= 0xf0; + tempbl >>= 4; + temp |= tempbl; + SiS_SetReg3(SiS_Pr->SiS_P3cb, temp); + temp = SiS_GetReg2(SiS_Pr->SiS_P3cd); + temp &= 0xf0; + tempbh &= 0x0f; + temp |= tempbh; + SiS_SetReg3(SiS_Pr->SiS_P3cd, temp); +} + +static void +SiS_WhatIsThis1b(SiS_Private *SiS_Pr, USHORT somevalue) +{ + USHORT temp, tempbl, tempbh; + + tempbl = tempbh = somevalue; + temp = SiS_GetReg2(SiS_Pr->SiS_P3cb); + temp &= 0x0f; + tempbl &= 0xf0; + temp |= tempbl; + SiS_SetReg3(SiS_Pr->SiS_P3cb, temp); + temp = SiS_GetReg2(SiS_Pr->SiS_P3cd); + temp &= 0x0f; + tempbh <<= 4; + temp |= tempbh; + SiS_SetReg3(SiS_Pr->SiS_P3cd, temp); +} + +static void +SiS_WhatIsThis2b(SiS_Private *SiS_Pr, USHORT somevalue) +{ + SiS_WhatIsThis1a(SiS_Pr, somevalue); + SiS_WhatIsThis1b(SiS_Pr, somevalue); +} + +static void +SiS_WhatIsThis1(SiS_Private *SiS_Pr) +{ + SiS_WhatIsThis2b(SiS_Pr, 0); +} + +static void +SiS_WhatIsThis2a(SiS_Private *SiS_Pr, USHORT somevalue) +{ + USHORT temp = somevalue >> 8; + + temp &= 0x07; + temp |= (temp << 4); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1d,temp); + SiS_WhatIsThis2b(SiS_Pr, somevalue); +} + +static void +SiS_WhatIsThis2(SiS_Private *SiS_Pr) +{ + SiS_WhatIsThis2a(SiS_Pr, 0); +} + +void +SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr) +{ + if(IS_SIS65x) { + SiS_WhatIsThis1(SiS_Pr); + SiS_WhatIsThis2(SiS_Pr); + } +} + void SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) { @@ -3023,9 +3226,16 @@ SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0]; if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { - if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { - SRdata |= 0x01; - } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + SRdata |= 0x01; + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_VBType & VB_NoLCD) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + SRdata |= 0x01; /* 8 dot clock */ + } + } + } } if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { @@ -3052,7 +3262,6 @@ SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) } } -/* Checked against 300, 650/301LVx 1.10.6s and 650/LVDS 1.10.07 BIOS */ void SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) { @@ -3069,7 +3278,6 @@ SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata); } -/* Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (630 code still there!) */ void SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT StandTableIndex) @@ -3088,13 +3296,12 @@ SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDevice (HwDeviceExtension->jChipRevision >= 0x30) ) { /* for 630S0 */ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { - SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE); } } } } -/* TW: Checked against 300, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 630/301B BIOS */ void SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension) @@ -3112,24 +3319,31 @@ SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex, } #endif if(i == 0x13) { + /* Pixel shift. If screen on LCD or TV is shifted left or right, + * this might be the cause. + */ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { - if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata=0; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata=0; } if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { - if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { - if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { - if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; - } - } + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; + } + } } if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { - if(HwDeviceExtension->jChipType >= SIS_315H) { - /* TW: From 650/LVDS 1.10.07, 1.10a; 650/301LVx 1.10.6s; not in 330 BIOS */ - ARdata = 0; - } else { - if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { - ARdata=0; - } + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(IS_SIS550650740660) { + /* 315, 330 don't do this */ + if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; + } else { + ARdata = 0; + } + } + } else { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; } } } @@ -3146,7 +3360,6 @@ SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex, SiS_GetReg2(SiS_Pr->SiS_P3da); } -/* TW: Checked against 300, 330, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */ void SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) { @@ -3163,7 +3376,6 @@ SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) } } -/* TW: Checked against 650/LVDS (1.10.07, 1.10a), 650/301LVx (1.10.6s) and 630/301B BIOS */ void SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) { @@ -3173,13 +3385,12 @@ SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00); /* Clear SR0A-SR0E */ } - /* TW: New from 330, 650/LVDS/301LV BIOSes: */ + /* TW: 330, 650/LVDS/301LV, 740/LVDS */ if(HwDeviceExtension->jChipType >= SIS_315H) { SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE); } } -/* TW: Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LV BIOS */ void SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex) { @@ -3197,7 +3408,6 @@ SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex) SiS_SetReg3(SiS_Pr->SiS_P3c2,temp); /* Set Misc(3c2) */ } -/* TW: Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS */ void SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefreshRateTableIndex, @@ -3207,7 +3417,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdI USHORT tempah,i,modeflag,j; #ifdef SIS315H USHORT temp; - USHORT ResInfo,DisplayType; + USHORT ResIndex,DisplayType; const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL; #endif @@ -3230,56 +3440,56 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdI /* LCDA */ temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, - RefreshRateTableIndex,&ResInfo,&DisplayType); + RefreshRateTableIndex,&ResIndex,&DisplayType); switch(DisplayType) { - case Panel_800x600 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1; break; - case Panel_1024x768 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break; - case Panel_1280x1024 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1; break; - case Panel_1400x1050 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1; break; - case Panel_1600x1200 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1; break; - case Panel_800x600 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H; break; - case Panel_1024x768 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H; break; - case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H; break; - case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H; break; - case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H; break; - case Panel_800x600 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2; break; - case Panel_1024x768 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2; break; - case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2; break; - case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2; break; - case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2; break; - case Panel_800x600 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H; break; - case Panel_1024x768 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H; break; - case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H; break; - case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H; break; - case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H; break; - default: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break; + case Panel_800x600 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1; break; + case Panel_1024x768 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break; + case Panel_1280x1024 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1; break; + case Panel_1400x1050 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1; break; + case Panel_1600x1200 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1; break; + case Panel_800x600 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H; break; + case Panel_1024x768 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H; break; + case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H; break; + case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H; break; + case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H; break; + case Panel_800x600 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2; break; + case Panel_1024x768 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2; break; + case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2; break; + case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2; break; + case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2; break; + case Panel_800x600 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H; break; + case Panel_1024x768 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H; break; + case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H; break; + case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H; break; + case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H; break; + default: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break; } - tempah = (LCDACRT1Ptr+ResInfo)->CR[0]; + tempah = (LCDACRT1Ptr+ResIndex)->CR[0]; SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah); for(i=0x01,j=1;i<=0x07;i++,j++){ - tempah = (LCDACRT1Ptr+ResInfo)->CR[j]; + tempah = (LCDACRT1Ptr+ResIndex)->CR[j]; SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); } for(i=0x10,j=8;i<=0x12;i++,j++){ - tempah = (LCDACRT1Ptr+ResInfo)->CR[j]; + tempah = (LCDACRT1Ptr+ResIndex)->CR[j]; SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); } for(i=0x15,j=11;i<=0x16;i++,j++){ - tempah =(LCDACRT1Ptr+ResInfo)->CR[j]; + tempah =(LCDACRT1Ptr+ResIndex)->CR[j]; SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); } for(i=0x0A,j=13;i<=0x0C;i++,j++){ - tempah = (LCDACRT1Ptr+ResInfo)->CR[j]; + tempah = (LCDACRT1Ptr+ResIndex)->CR[j]; SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah); } - tempah = (LCDACRT1Ptr+ResInfo)->CR[16]; + tempah = (LCDACRT1Ptr+ResIndex)->CR[16]; tempah &= 0x0E0; SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah); - tempah = (LCDACRT1Ptr+ResInfo)->CR[16]; + tempah = (LCDACRT1Ptr+ResIndex)->CR[16]; tempah &= 0x01; tempah <<= 5; if(modeflag & DoubleScanMode) tempah |= 0x080; @@ -3360,7 +3570,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdI BOOLEAN SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, - USHORT RefreshRateTableIndex,USHORT *ResInfo, + USHORT RefreshRateTableIndex,USHORT *ResIndex, USHORT *DisplayType) { USHORT tempbx=0,modeflag=0; @@ -3376,17 +3586,16 @@ SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT Mode tempbx = SiS_Pr->SiS_LCDResInfo; - if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 32; - if(modeflag & HalfDCLK) tempbx += 16; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32; + if(modeflag & HalfDCLK) tempbx += 16; - *ResInfo = CRT2CRTC & 0x3F; + *ResIndex = CRT2CRTC & 0x3F; *DisplayType = tempbx; return 1; } /* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */ -/* TW: Checked against 330, 650/LVDS (1.10.07), 650/301LV and 315 BIOS */ void SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefreshRateTableIndex, @@ -3425,14 +3634,14 @@ SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDevi USHORT index; /* TW: We only need to do this if Panel Link is to be - * initialized, thus on 630/LVDS/301B, and 650/LVDS + * initialized, thus on 630/LVDS/301BDH, and 650/LVDS */ if(HwDeviceExtension->jChipType >= SIS_315H) { - if (SiS_Pr->SiS_IF_DEF_LVDS == 0) return; + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return; } else { - if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && - (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) { - return; + if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && + (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) { + return; } } @@ -3456,7 +3665,6 @@ SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDevi SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80); } -/* TW: Checked against 300, 330, 650/LVDS, 650/301LVx, 315, 630/301B, 630/LVDS BIOS */ void SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension, @@ -3469,8 +3677,7 @@ SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdI RefreshRateTableIndex,HwDeviceExtension); } - if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) - && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){ + if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF); @@ -3525,7 +3732,6 @@ SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT Mod } #endif -/* TW: Checked against 300, 630/LVDS, 650/LVDS, 315 and 330 BIOS */ void SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex) @@ -3533,6 +3739,9 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDe USHORT data,data2,data3; USHORT infoflag=0,modeflag; USHORT resindex,xres; +#ifdef SIS315H + ULONG longdata; +#endif if(SiS_Pr->UseCustomMode) { modeflag = SiS_Pr->CModeFlag; @@ -3553,11 +3762,11 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDe data2 = 0; if(ModeNo > 0x13) { - if(SiS_Pr->SiS_ModeType > 0x02) { - data2 |= 0x02; - data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2; - data2 |= data3; - } + if(SiS_Pr->SiS_ModeType > 0x02) { + data2 |= 0x02; + data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2; + data2 |= data3; + } } #ifdef TWDEBUG xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n", @@ -3580,7 +3789,8 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDe if(HwDeviceExtension->jChipType != SIS_300) { data = 0x0000; if(infoflag & InterlaceMode) { - if(xres == 1024) data = 0x0035; + if(xres <= 800) data = 0x0020; + else if(xres <= 1024) data = 0x0035; else data = 0x0048; } data2 = data & 0x00FF; @@ -3612,6 +3822,7 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDe } else { SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7); } + /* 651 BIOS does something for mode 0x12 here */ } if(HwDeviceExtension->jChipType != SIS_300) { @@ -3667,9 +3878,9 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDe data2 *= data3; data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension); - data3 *= 1024; + longdata = data3 * 1024; - data2 = data3 / data2; + data2 = longdata / data2; if(SiS_Pr->SiS_ModeType != Mode16Bpp) { if(data2 >= 0x19c) data = 0xba; @@ -3713,7 +3924,6 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDe #endif } -/* TW: Checked against 300, 315, 330, 650/LVDS, 650/301LVx, 630/301B and 630/LVDS BIOS */ void SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,USHORT RefreshRateTableIndex, @@ -3743,7 +3953,7 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDevic if(VCLK >= 150) data2 |= 0x08; /* VCLK > 150 */ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2); - } else { /* 310/325 series */ + } else { /* 315 series */ data = 0; if(VCLK >= 166) data |= 0x0c; /* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */ @@ -3752,12 +3962,6 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDevic if(VCLK >= 166) { /* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7); } -#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */ - data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); /* DAC pedestal */ - data &= 0xE7; - if(VCLK<200) data |= 0x10; - SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data); /* DAC pedestal */ -#endif } data2 = 0x03; @@ -3780,7 +3984,6 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDevic } } -/* TW: Checked against 650/301LVx 1.10.6s, 315, 630/301B BIOS */ void SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) @@ -3822,11 +4025,10 @@ SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension, if(time == 256) j = 16; else j = time; - if( ( (HwDeviceExtension->jChipType == SIS_630) && /* 630/301B LCD */ - (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) && - (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) || - (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */ - (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */ + if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */ + (SiS_Pr->SiS_VBType & VB_NoLCD) ) || + (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */ + (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */ DACAddr = SiS_Pr->SiS_P3c8; DACData = SiS_Pr->SiS_P3c9; shiftflag = 0; @@ -3984,7 +4186,9 @@ GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) } else if((HwDeviceExtension->jChipType == SIS_550) || (HwDeviceExtension->jChipType == SIS_740) || - (HwDeviceExtension->jChipType == SIS_650)) { + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_660) || + (HwDeviceExtension->jChipType == SIS_760)) { counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F; counter++; @@ -4177,7 +4381,6 @@ SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT Refres } #endif -/* TW: Checked against 330, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 315 BIOS */ #ifdef SIS315H void SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, @@ -4402,7 +4605,7 @@ SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, }; i=0; - if(ModeNo >= 0x13) { + if(ModeNo > 0x13) { if(SiS_Pr->UseCustomMode) { VCLK = SiS_Pr->CSRClock; } else { @@ -4639,7 +4842,7 @@ SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) }; const USHORT PanelTypeTable31030x[16] = { 0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179, - 0x0189, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + 0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; const USHORT PanelTypeTable310LVDS[16] = { 0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188, @@ -4795,7 +4998,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UC SiS_Pr->SiS_SetFlag = 0x00; SiS_Pr->SiS_ModeType = ModeVGA; SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode; - SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension); + SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension); for(i=0;i<20;i++) { SiS_LongWait(SiS_Pr); } @@ -4833,7 +5036,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UC #ifdef SIS315H if(HwDeviceExtension->jChipType >= SIS_315H) { OutputSelect = ROMAddr[0xf3]; - if(HwDeviceExtension->jChipType == SIS_330) { + if(HwDeviceExtension->jChipType >= SIS_330) { OutputSelect = ROMAddr[0x11b]; } } @@ -4874,14 +5077,14 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UC tempcx=0; SiS_Sense(SiS_Pr, tempbx,tempcx); - if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) { - tempax &= 0x00ef; /* 301lv to disable CRT2*/ + if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) { + tempax &= 0x00ef; /* 30xlv have no VGA2*/ } SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,~0xDF,tempax); SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0); if(!(P2reg0 & 0x20)) { SiS_Pr->SiS_VBInfo = DisableCRT2Display; - SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension); + SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension); } } } @@ -4951,549 +5154,89 @@ SiS_SenseCHTV(SiS_Private *SiS_Pr) } #endif /* LINUXBIOS */ -/* ================ for TC only ================= */ - -#ifdef TC - -int -INT1AReturnCode(union REGS regs) -{ - if (regs.x.cflag) - { - /*printf("Error to find pci device!\n"); */ - return 1; - } - - switch(regs.h.ah) - { - case 0: return 0; - break; - case 0x81: printf("Function not support\n"); - break; - case 0x83: printf("bad vendor id\n"); - break; - case 0x86: printf("device not found\n"); - break; - case 0x87: printf("bad register number\n"); - break; - case 0x88: printf("set failed\n"); - break; - case 0x89: printf("buffer too small"); - break; - } - return 1; -} - -unsigned -FindPCIIOBase(unsigned index,unsigned deviceid) -{ - union REGS regs; - - regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */ - regs.h.al = 0x02; /*FIND_PCI_DEVICE */ - regs.x.cx = deviceid; - regs.x.dx = 0x1039; - regs.x.si = index; /* find n-th device */ - - int86(0x1A, ®s, ®s); - - if (INT1AReturnCode(regs)!=0) - return 0; - - /* regs.h.bh *//* bus number */ - /* regs.h.bl *//* device number */ - regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */ - regs.h.al = 0x09; /*READ_CONFIG_WORD */ - regs.x.cx = deviceid; - regs.x.dx = 0x1039; - regs.x.di = 0x18; /* register number */ - int86(0x1A, ®s, ®s); - - if (INT1AReturnCode(regs)!=0) - return 0; - return regs.x.cx; -} - - -void -main(int argc, char *argv[]) -{ - SIS_HW_DEVICE_INFO HwDeviceExtension; - USHORT temp; - USHORT ModeNo; - - /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */ - /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/ - -#ifdef SIS300 - HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30; - HwDeviceExtension.jChipType = SIS_630; -#endif - -#ifdef SIS315H -// HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30; -// HwDeviceExtension.jChipType = SIS_550; - HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30; - HwDeviceExtension.jChipType = SIS_315H; -#endif - - HwDeviceExtension.ujVBChipID = VB_CHIP_301; - strcpy(HwDeviceExtension.szVBIOSVer,"0.84"); - HwDeviceExtension.bSkipDramSizing = FALSE; - HwDeviceExtension.ulVideoMemorySize = 0; - if(argc==2) { - ModeNo=atoi(argv[1]); - } - else { - ModeNo=0x2e; - /*ModeNo=0x37; */ /* 1024x768x 4bpp */ - /*ModeNo=0x38; *//* 1024x768x 8bpp */ - /*ModeNo=0x4A; *//* 1024x768x 16bpp */ - /*ModeNo=0x47;*/ /* 800x600x 16bpp */ - } - /* SiSInit(SiS_Pr, &HwDeviceExtension);*/ - SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo); -} -#endif /* TC END */ - -/* ================ LINUX XFREE86 ====================== */ +/* ================ XFREE86 ================= */ /* Helper functions */ #ifdef LINUX_XF86 USHORT -SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - SISPtr pSiS = SISPTR(pScrn); - UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; - UShort ModeIndex = 0; - - if((pSiS->HaveCustomModes) && (!(mode->type & M_T_DEFAULT))) - return 0xfe; - - switch(mode->HDisplay) - { - case 320: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_320x480[i]; - } - break; - case 512: - if(mode->VDisplay == 384) { - ModeIndex = ModeIndex_512x384[i]; - } - break; - case 640: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_640x480[i]; - } else if(mode->VDisplay == 400) { - ModeIndex = ModeIndex_640x400[i]; - } - break; - case 720: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_720x480[i]; - } else if(mode->VDisplay == 576) { - ModeIndex = ModeIndex_720x576[i]; - } - break; - case 800: - if(mode->VDisplay == 600) { - ModeIndex = ModeIndex_800x600[i]; - } else if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_800x480[i]; - } - break; - case 848: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_848x480[i]; - } - break; - case 856: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_856x480[i]; - } - break; - case 1024: - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1024x768[i]; - } else if(mode->VDisplay == 576) { - ModeIndex = ModeIndex_1024x576[i]; - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(mode->VDisplay == 600) { - ModeIndex = ModeIndex_1024x600[i]; - } - } - break; - case 1152: - if(mode->VDisplay == 864) { - ModeIndex = ModeIndex_1152x864[i]; - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1152x768[i]; - } - } - break; - case 1280: - if(mode->VDisplay == 960) { - if(pSiS->VGAEngine == SIS_300_VGA) { - ModeIndex = ModeIndex_300_1280x960[i]; - } else { - ModeIndex = ModeIndex_310_1280x960[i]; - } - } else if (mode->VDisplay == 1024) { - ModeIndex = ModeIndex_1280x1024[i]; - } else if (mode->VDisplay == 720) { - ModeIndex = ModeIndex_1280x720[i]; - } else if(pSiS->VGAEngine == SIS_315_VGA) { - if (mode->VDisplay == 768) { - ModeIndex = ModeIndex_1280x768[i]; - } - } - break; - case 1360: - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1360x768[i]; - } - break; - case 1400: - if(pSiS->VGAEngine == SIS_315_VGA) { - if(mode->VDisplay == 1050) { - ModeIndex = ModeIndex_1400x1050[i]; - } - } - break; - case 1600: - if(mode->VDisplay == 1200) { - ModeIndex = ModeIndex_1600x1200[i]; - } - break; - case 1920: - if(mode->VDisplay == 1440) { - ModeIndex = ModeIndex_1920x1440[i]; - } - break; - case 2048: - if(mode->VDisplay == 1536) { - if(pSiS->VGAEngine == SIS_300_VGA) { - ModeIndex = ModeIndex_300_2048x1536[i]; - } else { - ModeIndex = ModeIndex_310_2048x1536[i]; - } - } - break; - } - - return(ModeIndex); -} - -USHORT -SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) -{ - SISPtr pSiS = SISPTR(pScrn); - UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; - UShort ModeIndex = 0; - - if(VBFlags & CRT2_LCD) { - - if( (mode->HDisplay <= pSiS->LCDwidth) && - (mode->VDisplay <= pSiS->LCDheight) ) { - - if(VBFlags & VB_LVDS) { /* LCD on LVDS */ - - switch(mode->HDisplay) - { - case 512: - if(mode->VDisplay == 384) { - if(pSiS->LCDwidth != 1024 || pSiS->LCDheight != 600) { /* not supported on 1024x600 panels */ - ModeIndex = ModeIndex_512x384[i]; - } - } - break; - case 640: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_640x480[i]; - } else if(mode->VDisplay == 400) { - ModeIndex = ModeIndex_640x400[i]; - } - break; - case 800: - if(mode->VDisplay == 600) { - ModeIndex = ModeIndex_800x600[i]; - } - break; - case 1024: - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1024x768[i]; - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(mode->VDisplay == 600) { - if(pSiS->LCDheight == 600) { /* This mode only supported on 1024x600 panels */ - ModeIndex = ModeIndex_1024x600[i]; - } - } - } - break; - case 1152: - if(pSiS->VGAEngine == SIS_300_VGA) { - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1152x768[i]; - } - } - break; - case 1280: - if(mode->VDisplay == 1024) { - ModeIndex = ModeIndex_1280x1024[i]; - } else if(pSiS->VGAEngine == SIS_315_VGA) { - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1280x768[i]; - } - } - break; - case 1400: - if(mode->VDisplay == 1050) { - if(pSiS->VGAEngine == SIS_315_VGA) { - ModeIndex = ModeIndex_1400x1050[i]; - } - } - break; - } - - } else { /* LCD on 301(B) */ - - switch(mode->HDisplay) - { - case 512: - if(mode->VDisplay == 384) { - ModeIndex = ModeIndex_512x384[i]; - } - break; - case 640: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_640x480[i]; - } else if(mode->VDisplay == 400) { - ModeIndex = ModeIndex_640x400[i]; - } - break; - case 800: - if(mode->VDisplay == 600) { - ModeIndex = ModeIndex_800x600[i]; - } - break; - case 1024: - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1024x768[i]; - } - break; - case 1280: - if(mode->VDisplay == 960) { - if(pSiS->VGAEngine == SIS_300_VGA) { - ModeIndex = ModeIndex_300_1280x960[i]; - } else { - ModeIndex = ModeIndex_310_1280x960[i]; - } - } else if (mode->VDisplay == 1024) { - ModeIndex = ModeIndex_1280x1024[i]; - } - break; - case 1400: - if(mode->VDisplay == 1050) { - if(pSiS->VGAEngine == SIS_315_VGA) { - ModeIndex = ModeIndex_1400x1050[i]; - } - } - break; - case 1600: - if(mode->VDisplay == 1200) { - ModeIndex = ModeIndex_1600x1200[i]; - } - break; - } - - } - - } - - } else if(VBFlags & CRT2_TV) { - - if(VBFlags & VB_CHRONTEL) { /* TV on Chrontel */ - - switch(mode->HDisplay) - { - case 512: - if(pSiS->VGAEngine == SIS_315_VGA) { - if(mode->VDisplay == 384) { - ModeIndex = ModeIndex_512x384[i]; - } - } - break; - case 640: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_640x480[i]; - } else if(mode->VDisplay == 400) { - ModeIndex = ModeIndex_640x400[i]; - } - break; - case 800: - if(mode->VDisplay == 600) { - ModeIndex = ModeIndex_800x600[i]; - } - break; - case 1024: - if(mode->VDisplay == 768) { - if(pSiS->VGAEngine == SIS_315_VGA) { - ModeIndex = ModeIndex_1024x768[i]; - } - } - break; - } - - } else { /* TV on 301(B/LV) */ - - switch(mode->HDisplay) - { - case 512: - if(mode->VDisplay == 384) { - ModeIndex = ModeIndex_512x384[i]; - } - break; - case 640: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_640x480[i]; - } - break; - case 720: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_720x480[i]; - } else if(mode->VDisplay == 576) { - ModeIndex = ModeIndex_720x576[i]; - } - break; - case 800: - if(mode->VDisplay == 600) { - ModeIndex = ModeIndex_800x600[i]; - } - break; - case 1024: /* Not supported with depth 32 */ - if((mode->VDisplay == 768) && (i != 3) ) { - if(VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) { - ModeIndex = ModeIndex_1024x768[i]; - } - } - break; - } - - } - - } else if(VBFlags & CRT2_VGA) { /* CRT2 is VGA2 */ - - switch(mode->HDisplay) - { - case 640: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_640x480[i]; - } else if(mode->VDisplay == 400) { - ModeIndex = ModeIndex_640x400[i]; - } - break; - case 800: - if(mode->VDisplay == 600) { - ModeIndex = ModeIndex_800x600[i]; - } else if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_800x480[i]; - } - break; - case 848: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_848x480[i]; - } - break; - case 856: - if(mode->VDisplay == 480) { - ModeIndex = ModeIndex_856x480[i]; - } - break; - case 1024: - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1024x768[i]; - } else if(mode->VDisplay == 576) { - ModeIndex = ModeIndex_1024x576[i]; - } - break; - case 1152: - if(mode->VDisplay == 864) { - ModeIndex = ModeIndex_1152x864[i]; - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(mode->VDisplay == 768) { - ModeIndex = ModeIndex_1152x768[i]; - } - } - break; - case 1280: - if (mode->VDisplay == 1024) { - ModeIndex = ModeIndex_1280x1024[i]; - } else if (mode->VDisplay == 720) { - ModeIndex = ModeIndex_1280x720[i]; - } else if(pSiS->VGAEngine == SIS_315_VGA) { - if (mode->VDisplay == 768) { - ModeIndex = ModeIndex_1280x768[i]; - } - } - break; - } - - } else { /* CRT1 only, no CRT2 */ - - ModeIndex = SiS_CalcModeIndex(pScrn, mode); - - } - - return(ModeIndex); -} - -USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) { SISPtr pSiS = SISPTR(pScrn); int out_n, out_dn, out_div, out_sbit, out_scale; int depth = pSiS->CurrentLayout.bitsPerPixel; - -#ifdef SISDUALHEAD - if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) || - ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0; -#else - if(VBFlags & DISPTYPE_DISP2) return 0; -#endif + unsigned int vclk[5]; + +#define Midx 0 +#define Nidx 1 +#define VLDidx 2 +#define Pidx 3 +#define PSNidx 4 + + pSiS->SiS_Pr->CModeFlag = 0; pSiS->SiS_Pr->CDClock = mode->Clock; - + pSiS->SiS_Pr->CHDisplay = mode->HDisplay; pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart; pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd; pSiS->SiS_Pr->CHTotal = mode->HTotal; - pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay; - pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal; - + pSiS->SiS_Pr->CVDisplay = mode->VDisplay; pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart; pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd; pSiS->SiS_Pr->CVTotal = mode->VTotal; + + pSiS->SiS_Pr->CFlags = mode->Flags; + + if(pSiS->SiS_Pr->CFlags & V_INTERLACE) { + pSiS->SiS_Pr->CVDisplay >>= 1; + pSiS->SiS_Pr->CVSyncStart >>= 1; + pSiS->SiS_Pr->CVSyncEnd >>= 1; + pSiS->SiS_Pr->CVTotal >>= 1; + } + if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) { + /* pSiS->SiS_Pr->CDClock <<= 1; */ + pSiS->SiS_Pr->CVDisplay <<= 1; + pSiS->SiS_Pr->CVSyncStart <<= 1; + pSiS->SiS_Pr->CVSyncEnd <<= 1; + pSiS->SiS_Pr->CVTotal <<= 1; + } + + pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay; + pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal; pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1; pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal; - - pSiS->SiS_Pr->CFlags = mode->Flags; - SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale); - + if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) { + pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00; + pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f); + pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f; + pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5); + pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n", - pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale); -#endif - - pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00; - pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f); - pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f; - pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5); - pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n", + pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale); +#endif + } else { + SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk); + pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00; + pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f; + pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f; + if(vclk[Pidx] <= 4) { + /* postscale 1,2,3,4 */ + pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5; + } else { + /* postscale 6,8 */ + pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5; + pSiS->SiS_Pr->CSR2C |= 0x80; + } +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n", + pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]); +#endif + } + pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1; pSiS->SiS_Pr->CCRT1CRTC[0] = ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff; @@ -5501,9 +5244,9 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) pSiS->SiS_Pr->CCRT1CRTC[2] = (pSiS->SiS_Pr->CHBlankStart >> 3) - 1; pSiS->SiS_Pr->CCRT1CRTC[3] = (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; pSiS->SiS_Pr->CCRT1CRTC[4] = (pSiS->SiS_Pr->CHSyncStart >> 3) + 3; - pSiS->SiS_Pr->CCRT1CRTC[5] = ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | + pSiS->SiS_Pr->CCRT1CRTC[5] = ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F); - + pSiS->SiS_Pr->CCRT1CRTC[6] = (pSiS->SiS_Pr->CVTotal - 2) & 0xFF; pSiS->SiS_Pr->CCRT1CRTC[7] = (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8) | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7) @@ -5513,50 +5256,50 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) | (((pSiS->SiS_Pr->CVTotal - 2) & 0x200) >> 4) | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3) | ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2); - + pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* cr9 */ - -#if 0 + +#if 0 if (mode->VScan >= 32) regp->CRTC[9] |= 0x1F; else if (mode->VScan > 1) regp->CRTC[9] |= mode->VScan - 1; -#endif +#endif - pSiS->SiS_Pr->CCRT1CRTC[8] = (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF; /* cr10 */ - pSiS->SiS_Pr->CCRT1CRTC[9] = ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80; /* cr11 */ - pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF; /* cr12 */ - pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF; /* cr15 */ - pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF; /* cr16 */ - - pSiS->SiS_Pr->CCRT1CRTC[13] = + pSiS->SiS_Pr->CCRT1CRTC[8] = (pSiS->SiS_Pr->CVSyncStart ) & 0xFF; /* cr10 */ + pSiS->SiS_Pr->CCRT1CRTC[9] = ((pSiS->SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* cr11 */ + pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF; /* cr12 */ + pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF; /* cr15 */ + pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF; /* cr16 */ + + pSiS->SiS_Pr->CCRT1CRTC[13] = GETBITSTR((pSiS->SiS_Pr->CVTotal -2), 10:10, 0:0) | GETBITSTR((pSiS->SiS_Pr->CVDisplay -1), 10:10, 1:1) | GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) | GETBITSTR((pSiS->SiS_Pr->CVSyncStart ), 10:10, 3:3) | GETBITSTR((pSiS->SiS_Pr->CVBlankEnd -1), 8:8, 4:4) | - GETBITSTR((pSiS->SiS_Pr->CVSyncEnd -1), 4:4, 5:5) ; + GETBITSTR((pSiS->SiS_Pr->CVSyncEnd ), 4:4, 5:5) ; - pSiS->SiS_Pr->CCRT1CRTC[14] = + pSiS->SiS_Pr->CCRT1CRTC[14] = GETBITSTR((pSiS->SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) | GETBITSTR((pSiS->SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) | GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) | GETBITSTR((pSiS->SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ; - + pSiS->SiS_Pr->CCRT1CRTC[15] = GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) | - GETBITSTR((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ; - + GETBITSTR((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ; + switch(depth) { - case 8: - pSiS->SiS_Pr->CModeFlag = 0x223b; + case 8: + pSiS->SiS_Pr->CModeFlag |= 0x223b; break; - case 16: - pSiS->SiS_Pr->CModeFlag = 0x227d; + case 16: + pSiS->SiS_Pr->CModeFlag |= 0x227d; break; - case 32: - pSiS->SiS_Pr->CModeFlag = 0x22ff; + case 32: + pSiS->SiS_Pr->CModeFlag |= 0x22ff; break; default: return 0; @@ -5570,9 +5313,9 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) pSiS->SiS_Pr->CModeFlag |= LineCompareOff; if(pSiS->SiS_Pr->CFlags & V_CLKDIV2) pSiS->SiS_Pr->CModeFlag |= HalfDCLK; - + pSiS->SiS_Pr->CInfoFlag = 0x0007; - if(pSiS->SiS_Pr->CFlags & V_NHSYNC) + if(pSiS->SiS_Pr->CFlags & V_NHSYNC) pSiS->SiS_Pr->CInfoFlag |= 0x4000; if(pSiS->SiS_Pr->CFlags & V_NVSYNC) pSiS->SiS_Pr->CInfoFlag |= 0x8000; @@ -5608,13 +5351,13 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) pSiS->SiS_Pr->CSR2B, pSiS->SiS_Pr->CSR2C, pSiS->SiS_Pr->CSRClock); -#endif +#endif return 1; } /* TW: Build a list of supported modes */ DisplayModePtr -SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) +SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi) { SISPtr pSiS = SISPTR(pScrn); unsigned short VRE, VBE, VRS, VBS, VDE, VT; @@ -5622,11 +5365,16 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) unsigned char sr_data, cr_data, cr_data2, cr_data3; unsigned char sr2b, sr2c; float num, denum, postscalar, divider; - int A, B, C, D, E, F, temp, i, j, index, vclkindex; - DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL; + int A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex; + DisplayModePtr new = NULL, current = NULL, first = NULL; + BOOLEAN done = FALSE; +#if 0 + DisplayModePtr backup = NULL; +#endif pSiS->backupmodelist = NULL; - + pSiS->AddedPlasmaModes = FALSE; + /* Initialize our pointers */ if(pSiS->VGAEngine == SIS_300_VGA) { #ifdef SIS300 @@ -5650,15 +5398,20 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F; #endif - if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) || - ((pSiS->DSTN) && - (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && - (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) && - (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480))) { + /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */ + if((!pSiS->FSTN) && + (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a)) { i++; continue; } - + if((pSiS->FSTN) && + (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) && + (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) && + (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) { + i++; + continue; + } + if(!(new = xalloc(sizeof(DisplayModeRec)))) return first; memset(new, 0, sizeof(DisplayModeRec)); if(!(new->name = xalloc(10))) { @@ -5672,13 +5425,13 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) } current = new; - + sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes, pSiS->SiS_Pr->SiS_RefIndex[i].YRes); current->status = MODE_OK; - current->type = M_T_DEFAULT; + current->type = M_T_DEFAULT; vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK; if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F; @@ -5691,7 +5444,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0); num = (sr2b & 0x7f) + 1.0; denum = (sr2c & 0x1f) + 1.0; - + #ifdef TWDEBUG xf86DrvMsg(0, X_INFO, "------------\n"); xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n", @@ -5759,10 +5512,29 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) D = B - F - C; - current->HDisplay = (E * 8); - current->HSyncStart = (E * 8) + (F * 8); - current->HSyncEnd = (E * 8) + (F * 8) + (C * 8); - current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8); + if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) && + ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) || + (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) { + + /* Terrible hack, but correct CRTC data for + * these modes only produces a black screen... + * (HRE is 0, leading into a too large C and + * a negative D. The CRT controller does not + * seem to like correcting HRE to 50 + */ + current->HDisplay = 320; + current->HSyncStart = 328; + current->HSyncEnd = 376; + current->HTotal = 400; + + } else { + + current->HDisplay = (E * 8); + current->HSyncStart = (E * 8) + (F * 8); + current->HSyncEnd = (E * 8) + (F * 8) + (C * 8); + current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8); + + } #ifdef TWDEBUG xf86DrvMsg(0, X_INFO, @@ -5886,7 +5658,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) current->VSyncStart <<= 1; current->VSyncEnd <<= 1; current->VTotal <<= 1; - current->VTotal |= 1; + current->VTotal |= 1; } if(current->Flags & V_DBLSCAN) { current->Clock >>= 1; @@ -5896,6 +5668,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) current->VTotal >>= 1; } +#if 0 if((backup = xalloc(sizeof(DisplayModeRec)))) { if(!pSiS->backupmodelist) pSiS->backupmodelist = backup; else { @@ -5914,6 +5687,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) backup->Flags = current->Flags; backup->Clock = current->Clock; } +#endif #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -5926,43 +5700,496 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) i++; } + /* Add non-standard LCD modes for panel's detailed timings */ + + if(!includelcdmodes) return first; + + xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n", + pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product); + + i = 0; + while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) { + + if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) { + + for(j=0; j<SiS_PlasmaTable[i].productnum; j++) { + + if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) { + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Identified %s panel, adding specific modes\n", + SiS_PlasmaTable[i].plasmaname); + + for(k=0; k<SiS_PlasmaTable[i].modenum; k++) { + + if(isfordvi) { + if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue; + } else { + if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue; + } + + if(!(new = xalloc(sizeof(DisplayModeRec)))) return first; + + memset(new, 0, sizeof(DisplayModeRec)); + if(!(new->name = xalloc(10))) { + xfree(new); + return first; + } + if(!first) first = new; + if(current) { + current->next = new; + new->prev = current; + } + + current = new; + + pSiS->AddedPlasmaModes = TRUE; + + l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f; + + sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay, + SiS_PlasmaMode[l].VDisplay); + + current->status = MODE_OK; + + current->type = M_T_BUILTIN; + + current->Clock = SiS_PlasmaMode[l].clock; + current->SynthClock = current->Clock; + + current->HDisplay = SiS_PlasmaMode[l].HDisplay; + current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch; + current->HSyncEnd = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth; + current->HTotal = SiS_PlasmaMode[l].HTotal; + + current->VDisplay = SiS_PlasmaMode[l].VDisplay; + current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch; + current->VSyncEnd = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth; + current->VTotal = SiS_PlasmaMode[l].VTotal; + + current->CrtcHDisplay = current->HDisplay; + current->CrtcHBlankStart = current->HSyncStart; + current->CrtcHSyncStart = current->HSyncStart; + current->CrtcHSyncEnd = current->HSyncEnd; + current->CrtcHBlankEnd = current->HSyncEnd; + current->CrtcHTotal = current->HTotal; + + current->CrtcVDisplay = current->VDisplay; + current->CrtcVBlankStart = current->VSyncStart; + current->CrtcVSyncStart = current->VSyncStart; + current->CrtcVSyncEnd = current->VSyncEnd; + current->CrtcVBlankEnd = current->VSyncEnd; + current->CrtcVTotal = current->VTotal; + + if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP) + current->Flags |= V_PHSYNC; + else + current->Flags |= V_NHSYNC; + + if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP) + current->Flags |= V_PVSYNC; + else + current->Flags |= V_NVSYNC; + + if(current->HDisplay > pSiS->LCDwidth) + pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay; + if(current->VDisplay > pSiS->LCDheight) + pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay; + + } + done = TRUE; + break; + } + } + } + + i++; + + } + + if(pSiS->SiS_Pr->CP_HaveCustomData) { + + for(i=0; i<7; i++) { + + if(pSiS->SiS_Pr->CP_DataValid[i]) { + + if(!(new = xalloc(sizeof(DisplayModeRec)))) return first; + + memset(new, 0, sizeof(DisplayModeRec)); + if(!(new->name = xalloc(10))) { + xfree(new); + return first; + } + if(!first) first = new; + if(current) { + current->next = new; + new->prev = current; + } + + current = new; + + sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i], + pSiS->SiS_Pr->CP_VDisplay[i]); + + current->status = MODE_OK; + + current->type = M_T_BUILTIN; + + current->Clock = pSiS->SiS_Pr->CP_Clock[i]; + current->SynthClock = current->Clock; + + current->HDisplay = pSiS->SiS_Pr->CP_HDisplay[i]; + current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i]; + current->HSyncEnd = pSiS->SiS_Pr->CP_HSyncEnd[i]; + current->HTotal = pSiS->SiS_Pr->CP_HTotal[i]; + + current->VDisplay = pSiS->SiS_Pr->CP_VDisplay[i]; + current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i]; + current->VSyncEnd = pSiS->SiS_Pr->CP_VSyncEnd[i]; + current->VTotal = pSiS->SiS_Pr->CP_VTotal[i]; + + current->CrtcHDisplay = current->HDisplay; + current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i]; + current->CrtcHSyncStart = current->HSyncStart; + current->CrtcHSyncEnd = current->HSyncEnd; + current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i]; + current->CrtcHTotal = current->HTotal; + + current->CrtcVDisplay = current->VDisplay; + current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i]; + current->CrtcVSyncStart = current->VSyncStart; + current->CrtcVSyncEnd = current->VSyncEnd; + current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i]; + current->CrtcVTotal = current->VTotal; + + if(pSiS->SiS_Pr->CP_SyncValid[i]) { + if(pSiS->SiS_Pr->CP_HSync_P[i]) + current->Flags |= V_PHSYNC; + else + current->Flags |= V_NHSYNC; + + if(pSiS->SiS_Pr->CP_VSync_P[i]) + current->Flags |= V_PVSYNC; + else + current->Flags |= V_NVSYNC; + } else { + /* No sync data? Use positive sync... */ + current->Flags |= V_PHSYNC; + current->Flags |= V_PVSYNC; + } + } + } + } + return first; } +#endif -#define MODEID_OFF 0x449 - -unsigned char -SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id) +#ifdef LINUX_KERNEL +int +sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + unsigned char modeno, unsigned char rateindex) { - return(SiS_GetSetBIOSScratch(pScrn, MODEID_OFF, id)); + USHORT ModeNo = modeno; + USHORT ModeIdIndex = 0, ClockIndex = 0; + USHORT RefreshRateTableIndex = 0; + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + ULONG temp = 0; + int Clock; + + if(HwDeviceExtension->jChipType < SIS_315H) { +#ifdef SIS300 + InitTo300Pointer(SiS_Pr, HwDeviceExtension); +#else + return 65 * 1000 * 1000; +#endif + } else { +#ifdef SIS315H + InitTo310Pointer(SiS_Pr, HwDeviceExtension); +#else + return 65 * 1000 * 1000; +#endif + } + + temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex); + if(!temp) { + printk(KERN_ERR "Could not find mode %x\n", ModeNo); + return 65 * 1000 * 1000; + } + + RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; + RefreshRateTableIndex += (rateindex - 1); + ClockIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + if(HwDeviceExtension->jChipType < SIS_315H) { + ClockIndex &= 0x3F; + } + Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000 * 1000; + + return(Clock); } -unsigned char -SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value) +BOOLEAN +sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex) { - unsigned char ret; - unsigned char *base; - - base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000); - if(!base) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "(init.c: Could not map BIOS scratch area)\n"); - return 0; + USHORT ModeNo = modeno; + USHORT ModeIdIndex = 0, CRT1Index = 0; + USHORT RefreshRateTableIndex = 0; + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + ULONG temp = 0; + unsigned char sr_data, cr_data, cr_data2; + + if(HwDeviceExtension->jChipType < SIS_315H) { +#ifdef SIS300 + InitTo300Pointer(SiS_Pr, HwDeviceExtension); +#else + return FALSE; +#endif + } else { +#ifdef SIS315H + InitTo310Pointer(SiS_Pr, HwDeviceExtension); +#else + return FALSE; +#endif } - ret = *(base + offset); + temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex); + if(!temp) return FALSE; + + RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; + RefreshRateTableIndex += (rateindex - 1); + CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + + sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14]; + cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0]; + *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8; - /* value != 0xff means: set register */ - if (value != 0xff) - *(base + offset) = value; + sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13]; + cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6]; + cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7]; + *vtotal = ((cr_data & 0xFF) | + ((unsigned short)(cr_data2 & 0x01) << 8) | + ((unsigned short)(cr_data2 & 0x20) << 4) | + ((unsigned short)(sr_data & 0x01) << 10)) + 2; - xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000); + if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode) + *vtotal *= 2; - return ret; + return TRUE; } +int +sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + unsigned char modeno, unsigned char rateindex, + ULONG *left_margin, ULONG *right_margin, + ULONG *upper_margin, ULONG *lower_margin, + ULONG *hsync_len, ULONG *vsync_len, + ULONG *sync, ULONG *vmode) +{ + USHORT ModeNo = modeno; + USHORT ModeIdIndex = 0, index = 0; + USHORT RefreshRateTableIndex = 0; + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + unsigned short VRE, VBE, VRS, VBS, VDE, VT; + unsigned short HRE, HBE, HRS, HBS, HDE, HT; + unsigned char sr_data, cr_data, cr_data2, cr_data3; + int A, B, C, D, E, F, temp, j; + + if(HwDeviceExtension->jChipType < SIS_315H) { +#ifdef SIS300 + InitTo300Pointer(SiS_Pr, HwDeviceExtension); +#else + return 0; +#endif + } else { +#ifdef SIS315H + InitTo310Pointer(SiS_Pr, HwDeviceExtension); +#else + return 0; #endif + } + + temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex); + if(!temp) return 0; + + RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; + RefreshRateTableIndex += (rateindex - 1); + index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + sr_data = SiS_Pr->SiS_CRT1Table[index].CR[14]; + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[0]; + + /* Horizontal total */ + HT = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x03) << 8); + A = HT + 5; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[1]; + + /* Horizontal display enable end */ + HDE = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x0C) << 6); + E = HDE + 1; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[4]; + + /* Horizontal retrace (=sync) start */ + HRS = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0xC0) << 2); + F = HRS - E - 3; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[2]; + + /* Horizontal blank start */ + HBS = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x30) << 4); + + sr_data = SiS_Pr->SiS_CRT1Table[index].CR[15]; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[3]; + + cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[5]; + + /* Horizontal blank end */ + HBE = (cr_data & 0x1f) | + ((unsigned short) (cr_data2 & 0x80) >> 2) | + ((unsigned short) (sr_data & 0x03) << 6); + + /* Horizontal retrace (=sync) end */ + HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3); + + temp = HBE - ((E - 1) & 255); + B = (temp > 0) ? temp : (temp + 256); + + temp = HRE - ((E + F + 3) & 63); + C = (temp > 0) ? temp : (temp + 64); + + D = B - F - C; + + if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) && + ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) || + (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) { + + /* Terrible hack, but the correct CRTC data for + * these modes only produces a black screen... + */ + *left_margin = (400 - 376); + *right_margin = (328 - 320); + *hsync_len = (376 - 328); + + } else { + + *left_margin = D * 8; + *right_margin = F * 8; + *hsync_len = C * 8; + + } + + sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13]; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6]; + + cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7]; + + /* Vertical total */ + VT = (cr_data & 0xFF) | + ((unsigned short) (cr_data2 & 0x01) << 8) | + ((unsigned short)(cr_data2 & 0x20) << 4) | + ((unsigned short) (sr_data & 0x01) << 10); + A = VT + 2; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[10]; + + /* Vertical display enable end */ + VDE = (cr_data & 0xff) | + ((unsigned short) (cr_data2 & 0x02) << 7) | + ((unsigned short) (cr_data2 & 0x40) << 3) | + ((unsigned short) (sr_data & 0x02) << 9); + E = VDE + 1; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[8]; + + /* Vertical retrace (=sync) start */ + VRS = (cr_data & 0xff) | + ((unsigned short) (cr_data2 & 0x04) << 6) | + ((unsigned short) (cr_data2 & 0x80) << 2) | + ((unsigned short) (sr_data & 0x08) << 7); + F = VRS + 1 - E; + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[11]; + + cr_data3 = (SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5; + + /* Vertical blank start */ + VBS = (cr_data & 0xff) | + ((unsigned short) (cr_data2 & 0x08) << 5) | + ((unsigned short) (cr_data3 & 0x20) << 4) | + ((unsigned short) (sr_data & 0x04) << 8); + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[12]; + + /* Vertical blank end */ + VBE = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x10) << 4); + temp = VBE - ((E - 1) & 511); + B = (temp > 0) ? temp : (temp + 512); + + cr_data = SiS_Pr->SiS_CRT1Table[index].CR[9]; + + /* Vertical retrace (=sync) end */ + VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1); + temp = VRE - ((E + F - 1) & 31); + C = (temp > 0) ? temp : (temp + 32); + + D = B - F - C; + + *upper_margin = D; + *lower_margin = F; + *vsync_len = C; + + if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000) + *sync &= ~FB_SYNC_VERT_HIGH_ACT; + else + *sync |= FB_SYNC_VERT_HIGH_ACT; + + if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000) + *sync &= ~FB_SYNC_HOR_HIGH_ACT; + else + *sync |= FB_SYNC_HOR_HIGH_ACT; + + *vmode = FB_VMODE_NONINTERLACED; + if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080) + *vmode = FB_VMODE_INTERLACED; + else { + j = 0; + while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) { + if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID == + SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) { + if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) { + *vmode = FB_VMODE_DOUBLE; + } + break; + } + j++; + } + } + + if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { +#if 0 /* Do this? */ + *upper_margin <<= 1; + *lower_margin <<= 1; + *vsync_len <<= 1; +#endif + } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { + *upper_margin >>= 1; + *lower_margin >>= 1; + *vsync_len >>= 1; + } + + return 1; +} + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/init.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.h index 86635092d..c340c2534 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/init.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.h @@ -1,21 +1,47 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.h,v 1.5 2003/02/10 01:14:16 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.h,v 1.15 2003/08/07 12:52:22 twini Exp $ */ +/* + * Data and prototypes for init.c + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * Based on code by Silicon Intergrated Systems + * + */ #ifndef _INIT_ #define _INIT_ #include "osdef.h" + #include "initdef.h" #include "vgatypes.h" #include "vstruct.h" -#ifdef TC -#include <stdio.h> -#include <string.h> -#include <conio.h> -#include <dos.h> -#include <stdlib.h> -#endif - #ifdef LINUX_XF86 #include "xf86.h" #include "xf86Pci.h" @@ -26,22 +52,19 @@ #endif #ifdef LINUX_KERNEL +#ifdef SIS_CP +#undef SIS_CP +#endif +#include <linux/config.h> +#include <linux/version.h> #include <linux/types.h> #include <asm/io.h> +#include <linux/fb.h> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #include <linux/sisfb.h> +#else +#include <video/sisfb.h> #endif - -#ifdef WIN2000 -#include <stdio.h> -#include <string.h> -#include <miniport.h> -#include "dderror.h" -#include "devioctl.h" -#include "miniport.h" -#include "ntddvdeo.h" -#include "video.h" -#include "sisv.h" -#include "tools.h" #endif const USHORT SiS_DRAMType[17][5]={ @@ -139,6 +162,2228 @@ const USHORT SiS_VGA_DAC[] = 0x0B,0x0C,0x0D,0x0F,0x10 }; +static const SiS_StResInfoStruct SiS_StResInfo[]= +{ + { 640,400}, + { 640,350}, + { 720,400}, + { 720,350}, + { 640,480} +}; + +static const SiS_ModeResInfoStruct SiS_ModeResInfo[] = +{ + { 320, 200, 8, 8}, /* 0x00 */ + { 320, 240, 8, 8}, /* 0x01 */ + { 320, 400, 8, 8}, /* 0x02 */ + { 400, 300, 8, 8}, /* 0x03 */ + { 512, 384, 8, 8}, /* 0x04 */ + { 640, 400, 8,16}, /* 0x05 */ + { 640, 480, 8,16}, /* 0x06 */ + { 800, 600, 8,16}, /* 0x07 */ + { 1024, 768, 8,16}, /* 0x08 */ + { 1280,1024, 8,16}, /* 0x09 */ + { 1600,1200, 8,16}, /* 0x0a */ + { 1920,1440, 8,16}, /* 0x0b */ + { 2048,1536, 8,16}, /* 0x0c */ + { 720, 480, 8,16}, /* 0x0d */ + { 720, 576, 8,16}, /* 0x0e */ + { 1280, 960, 8,16}, /* 0x0f */ + { 800, 480, 8,16}, /* 0x10 */ + { 1024, 576, 8,16}, /* 0x11 */ + { 1280, 720, 8,16}, /* 0x12 */ + { 856, 480, 8,16}, /* 0x13 */ + { 1280, 768, 8,16}, /* 0x14 */ + { 1400,1050, 8,16}, /* 0x15 */ + { 1152, 864, 8,16}, /* 0x16 */ + { 848, 480, 8,16}, /* 0x17 */ + { 1360, 768, 8,16}, /* 0x18 */ + { 1024, 600, 8,16}, /* 0x19 */ + { 1152, 768, 8,16}, /* 0x1a */ + { 768, 576, 8,16}, /* 0x1b */ + { 1360,1024, 8,16} /* 0x1c */ +}; + +static SiS_StandTableStruct SiS_StandTable[]= +{ +/* 0x00: MD_0_200 */ + { + 0x28,0x18,0x08,0x0800, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x01: MD_1_200 */ + { + 0x28,0x18,0x08,0x0800, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x02: MD_2_200 */ + { + 0x50,0x18,0x08,0x1000, + {0x01,0x03,0x00,0x02}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x03: MD_3_200 - mode 0x03 - 0 */ + { + 0x50,0x18,0x08,0x1000, + {0x01,0x03,0x00,0x02}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x04: MD_4 */ + { + 0x28,0x18,0x08,0x4000, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */ + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, + 0xff}, + {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x03,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, + 0xff} + }, +/* 0x05: MD_5 */ + { + 0x28,0x18,0x08,0x4000, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */ + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, + 0xff}, + {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x03,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, + 0xff} + }, +/* 0x06: MD_6 */ + { + 0x50,0x18,0x08,0x4000, + {0x01,0x01,0x00,0x06}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */ + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2, + 0xff}, + {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x01,0x00,0x01,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00, + 0xff} + }, +/* 0x07: MD_7 */ + { + 0x50,0x18,0x0e,0x1000, + {0x00,0x03,0x00,0x03}, + 0xa6, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3, + 0xff}, + {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x0e,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, + 0xff} + }, +/* 0x08: MDA_DAC */ + { + 0x00,0x00,0x00,0x0000, + {0x00,0x00,0x00,0x15}, + 0x15, + {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00, + 0x00}, + {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15}, + {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x3f} + }, +/* 0x09: CGA_DAC */ + { + 0x00,0x10,0x04,0x0114, + {0x11,0x09,0x15,0x00}, + 0x10, + {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a, + 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a, + 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10, + 0x04}, + {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04, + 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e, + 0x3e,0x2b,0x3b,0x2f}, + {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, + 0x3f} + }, +/* 0x0a: EGA_DAC */ + { + 0x00,0x10,0x04,0x0114, + {0x11,0x05,0x15,0x20}, + 0x30, + {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18, + 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38, + 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12, + 0x06}, + {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26, + 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e, + 0x1e,0x0b,0x1b,0x0f}, + {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, + 0x3f} + }, +/* 0x0b: VGA_DAC */ + { + 0x00,0x10,0x04,0x0114, + {0x11,0x09,0x15,0x2a}, + 0x3a, + {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05, + 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20, + 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10, + 0x1f}, + {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d, + 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15, + 0x1c,0x0e,0x11,0x15}, + {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00, + 0x04} + }, +/* 0x0c */ + { + 0x08,0x0c,0x10,0x0a08, + {0x0c,0x0e,0x10,0x0b}, + 0x0c, + {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00, + 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00, + 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00, + 0x06}, + {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08, + 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00, + 0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00} + }, +/* 0x0d: MD_D */ + { + 0x28,0x18,0x08,0x2000, + {0x09,0x0f,0x00,0x06}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 2c is 2b for 300 */ + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* 0x0e: MD_E */ + { + 0x50,0x18,0x08,0x4000, + {0x01,0x0f,0x00,0x06}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */ + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* 0x0f: ExtVGATable - modes > 0x13 */ + { + 0x00,0x00,0x00,0x0000, + {0x01,0x0f,0x00,0x0e}, + 0x23, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x01,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, + 0xff} + }, +/* 0x10: ROM_SAVEPTR - totally different for 300 */ + { + 0x9f,0x3b,0x00,0x00c0, + {0x00,0x00,0x00,0x00}, + 0x00, + {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0, + 0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00} + }, +/* 0x11: MD_F */ + { + 0x50,0x18,0x0e,0x8000, + {0x01,0x0f,0x00,0x06}, + 0xa2, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */ + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */ + 0xff}, + {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00, + 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00, + 0x0b,0x00,0x05,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05, + 0xff} + }, +/* 0x12: MD_10 */ + { + 0x50,0x18,0x0e,0x8000, + {0x01,0x0f,0x00,0x06}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */ + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */ + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* 0x13: MD_0_350 */ + { + 0x28,0x18,0x0e,0x0800, + {0x09,0x03,0x00,0x02}, + 0xa3, + {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */ + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x14: MD_1_350 */ + { + 0x28,0x18,0x0e,0x0800, + {0x09,0x03,0x00,0x02}, + 0xa3, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x15: MD_2_350 */ + { + 0x50,0x18,0x0e,0x1000, + {0x01,0x03,0x00,0x02}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x16: MD_3_350 - mode 0x03 - 1 */ + { + 0x50,0x18,0x0e,0x1000, + {0x01,0x03,0x00,0x02}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x17: MD_0_1_400 */ + { + 0x28,0x18,0x10,0x0800, + {0x08,0x03,0x00,0x02}, + 0x67, + {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */ + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x0c,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x18: MD_2_3_400 - mode 0x03 - 2 */ + { + 0x50,0x18,0x10,0x1000, + {0x00,0x03,0x00,0x02}, + 0x67, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x0c,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* 0x19: MD_7_400 */ + { + 0x50,0x18,0x10,0x1000, + {0x00,0x03,0x00,0x02}, + 0x66, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x0e,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, + 0xff} + }, +/* 0x1a: MD_11 */ + { + 0x50,0x1d,0x10,0xa000, + {0x01,0x0f,0x00,0x06}, + 0xe3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */ + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3, /* e9,8b is ea,8c on 300 */ + 0xff}, + {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01, + 0xff} + }, +/* 0x1b: ExtEGATable - Modes <= 0x02 */ + { + 0x50,0x1d,0x10,0xa000, + {0x01,0x0f,0x00,0x06}, + 0xe3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */ + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, /* e9,8b is ea,8c on 300 */ + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* 0x1c: MD_13 */ + { + 0x28,0x18,0x08,0x2000, + {0x01,0x0f,0x00,0x0e}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */ + 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x41,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, + 0xff} + } +}; + +static const UCHAR SiS_NTSCTiming[] = { + 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, + 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, + 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b, + 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, + 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, + 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50, + 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 +}; + +static const UCHAR SiS_PALTiming[] = { + 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70, + 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b, + 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17, + 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02, + 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63, + 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00 +}; + +static const UCHAR SiS_HiTVExtTiming[] = { + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, + 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, + 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, + 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 +}; + +static const UCHAR SiS_HiTVSt1Timing[] = { + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03, + 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10, + 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86, + 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00 +}; + +static const UCHAR SiS_HiTVSt2Timing[] = { + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, + 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, + 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, + 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 +}; + +static const UCHAR SiS_HiTVTextTiming[] = { + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03, + 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20, + 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96, + 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00 +}; + +static const UCHAR SiS_HiTVGroup3Data[] = { + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f, + 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9, + 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; + +static const UCHAR SiS_HiTVGroup3Simu[] = { + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95, + 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4, + 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; + +static const UCHAR SiS_HiTVGroup3Text[] = { + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7, + 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca, + 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; + +static const UCHAR SiS_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* Was {0x21,0xed,0x8a,0x08}; */ +static const UCHAR SiS_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* Was {0x2a,0x05,0xd3,0x00}; */ +static const UCHAR SiS_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; +static const UCHAR SiS_PALNPhase[] = {0x21,0xF4,0x3E,0xBA}; +static const UCHAR SiS_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6}; +static const UCHAR SiS_PALPhase2[] = {0x2a,0x09,0x86,0xe9}; +static const UCHAR SiS_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; +static const UCHAR SiS_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; +static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a}; + +static const SiS_TVDataStruct SiS_StPALData[]= +{ + { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, + { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, + { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22} +}; + +static const SiS_TVDataStruct SiS_ExtPALData[] = +{ + { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */ + { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, + { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18}, + { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a}, + { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */ +/*{ 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16},*//* 800x600, 400x300 */ + { 36, 25,1060, 648,1270, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 - better */ + { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x576 */ + { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} /* 1024x768 */ +}; + +static const SiS_TVDataStruct SiS_StNTSCData[]= +{ + { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, + { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18} +}; + +static const SiS_TVDataStruct SiS_ExtNTSCData[]= +{ + { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */ + { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a}, + { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */ + { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */ + { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */ +/*{ 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08},*/ /* 720x480 (old, from 650) */ + { 1, 1,1100, 811,1412, 440, 0, 128, 0,0xee,0x0c,0x22,0x08} /* 1024x768 CORRECTED */ +/*{ 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} */ /* 1024x768 */ +#if 0 /* 300 series was: */ + { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, + { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a}, + { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, + { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, + { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, + { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xf1,0x04,0x1f,0x18} +#endif +}; + + +static const SiS_TVDataStruct SiS_St2HiTVData[]= +{ + { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, + { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00}, + { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, + { 1, 1, 0x3e8,0x233,0x311,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00}, + { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00}, + { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00} +}; + +static const SiS_TVDataStruct SiS_ExtHiTVData[]= +{ + { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, + { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, + { 3, 1, 0x348,0x1e3,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, + { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, + { 5, 1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */ + { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */ + { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */ + { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x1024 */ + { 4, 1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x480 */ + { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x576 */ + { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00} /* 1280x720 */ +}; + +static const UCHAR SiS_OutputSelect = 0x40; + +static const UCHAR SiS_SoftSetting = 0x30; /* RAM setting */ + +static const SiS_LCDDataStruct SiS_LCD1280x960Data[] = +{ + { 9, 2, 800, 500,1800,1000}, + { 9, 2, 800, 500,1800,1000}, + { 4, 1, 900, 500,1800,1000}, + { 4, 1, 900, 500,1800,1000}, + { 9, 2, 800, 500,1800,1000}, + { 30, 11,1056, 625,1800,1000}, + { 5, 3,1350, 800,1800,1000}, + { 1, 1,1576,1050,1576,1050}, + { 1, 1,1800,1000,1800,1000} +}; + +static const SiS_LCDDataStruct SiS_StLCD1280x768Data[] = +{ + { 211, 100, 2100, 408, 1688, 802 }, /* These values are *wrong* */ + { 211, 64, 1536, 358, 1688, 802 }, /* (which is why they aren't used yet) */ + { 211, 100, 2100, 408, 1688, 802 }, + { 211, 64, 1536, 358, 1688, 802 }, + { 211, 48, 840, 488, 1688, 802 }, + { 211, 72, 1008, 609, 1688, 802 }, + { 211, 128, 1400, 776, 1688, 802 }, + { 211, 205, 1680, 1041, 1688, 802 }, + { 1, 1, 1688, 802, 1688, 802 } /* That's the only one that *might* be correct */ +}; + +static const SiS_LCDDataStruct SiS_ExtLCD1280x768Data[] = +{ + { 211, 100, 2100, 408, 1688, 802 }, /* These values are *wrong* */ + { 211, 64, 1536, 358, 1688, 802 }, /* (which is why they aren't used yet) */ + { 211, 100, 2100, 408, 1688, 802 }, + { 211, 64, 1536, 358, 1688, 802 }, + { 211, 48, 840, 488, 1688, 802 }, + { 211, 72, 1008, 609, 1688, 802 }, + { 211, 128, 1400, 776, 1688, 802 }, + { 211, 205, 1680, 1041, 1688, 802 }, + { 1, 1, 1688, 802, 1688, 802 } /* That's the only one that *might* be correct */ +}; + +static const SiS_LCDDataStruct SiS_NoScaleData1280x768[] = +{ /* All values guessed */ + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802}, + { 1, 1, 1688, 802, 1688, 802} +}; + +static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] = +{ + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 48, 840, 488, 1688, 1066 }, + { 211, 72, 1008, 609, 1688, 1066 }, + { 211, 128, 1400, 776, 1688, 1066 }, + { 211, 205, 1680, 1041, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 } +}; + +static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] = +{ + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 48, 840, 488, 1688, 1066 }, + { 211, 72, 1008, 609, 1688, 1066 }, + { 211, 128, 1400, 776, 1688, 1066 }, + { 211, 205, 1680, 1041, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 } +}; + +static const SiS_LCDDataStruct SiS_NoScaleData1400x1050[] = +{ + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 } +}; + +static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] = +{ + {27, 4, 800, 500, 2160, 1250 }, + {27, 4, 800, 500, 2160, 1250 }, + { 6, 1, 900, 500, 2160, 1250 }, + { 6, 1, 900, 500, 2160, 1250 }, + {27, 1, 800, 500, 2160, 1250 }, + { 4, 1,1080, 625, 2160, 1250 }, + { 5, 2,1350, 800, 2160, 1250 }, + {135,88,1600,1100, 2160, 1250 }, + {135,88,1600,1100, 2160, 1250 }, + { 1, 1,2160,1250, 2160, 1250 } +}; + +static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] = +{ + {27, 4, 800, 500, 2160, 1250 }, + {27, 4, 800, 500, 2160, 1250 }, + { 6, 1, 900, 500, 2160, 1250 }, + { 6, 1, 900, 500, 2160, 1250 }, + {27, 1, 800, 500, 2160, 1250 }, + { 4, 1,1080, 625, 2160, 1250 }, + { 5, 2,1350, 800, 2160, 1250 }, + {27,16,1500,1064, 2160, 1250 }, + {27,16,1500,1064, 2160, 1250 }, + { 1, 1,2160,1250, 2160, 1250 } +}; + +static const SiS_LCDDataStruct SiS_NoScaleData1600x1200[] = +{ + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, + {1, 1, 2160, 1250, 2048, 1250}, +}; + +static const SiS_LCDDataStruct SiS_NoScaleData[] = +{ + { 1, 1, 800, 449, 800, 449 }, + { 1, 1, 800, 449, 800, 449 }, + { 1, 1, 900, 449, 900, 449 }, + { 1, 1, 900, 449, 900, 449 }, + { 1, 1, 800, 525, 800, 525 }, + { 1, 1,1056, 628,1056, 628 }, + { 1, 1,1344, 806,1344, 806 }, + { 1, 1,1688,1066,1688,1066 }, + { 1, 1,1688, 802,1688, 802 }, /* 1280x768: 802 was 806 in both cases */ + { 1, 1,2160,1250,2160,1250 }, /* 1600x1200 */ + { 1, 1,1800,1000,1800,1000 } /* 1280x960 */ +}; + +static const SiS_LVDSDataStruct SiS_LVDS320x480Data_1[]= +{ + { 848, 433, 400, 525}, + { 848, 389, 400, 525}, + { 848, 433, 400, 525}, + { 848, 389, 400, 525}, + { 848, 518, 400, 525}, + {1056, 628, 400, 525}, + { 400, 525, 400, 525}, + { 800, 449,1000, 644}, + { 800, 525,1000, 635} +}; + +static const SiS_LVDSDataStruct SiS_LVDS800x600Data_1[]= +{ + { 848, 433,1060, 629}, + { 848, 389,1060, 629}, + { 848, 433,1060, 629}, + { 848, 389,1060, 629}, + { 848, 518,1060, 629}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + { 800, 449,1000, 644}, + { 800, 525,1000, 635} +}; + +static const SiS_LVDSDataStruct SiS_LVDS800x600Data_2[]= +{ + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + { 800, 449,1000, 644}, + { 800, 525,1000, 635} +}; + + + +static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_1[]= +{ + {1048, 442,1688,1066}, + {1048, 392,1688,1066}, + {1048, 442,1688,1066}, + {1048, 392,1688,1066}, + {1048, 522,1688,1066}, + {1208, 642,1688,1066}, + {1432, 810,1688,1066}, + {1688,1066,1688,1066} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_2[]= +{ + {1688,1066,1688,1066}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_1[]= +{ + { 840, 438,1344, 806}, + { 840, 409,1344, 806}, + { 840, 438,1344, 806}, + { 840, 409,1344, 806}, + { 840, 518,1344, 806}, /* 640x480 */ + {1050, 638,1344, 806}, /* 800x600 */ + {1344, 806,1344, 806}, /* 1024x768 */ + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_2[]= +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +/* Custom data for Barco iQ R300 */ +static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_1[]= +{ + { 832, 438,1331, 806}, + { 832, 388,1331, 806}, + { 832, 438,1331, 806}, + { 832, 388,1331, 806}, + { 832, 518,1331, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066} /* 1360x1024 */ +}; + +/* Custom data for Barco iQ R300 */ +static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_2[]= +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1688,1066,1688,1066}, + {1688,1066,1688,1066} /* 1360x1024 */ +}; + +static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_1[]= +{ + { 832, 438,1331, 806}, + { 832, 409,1331, 806}, + { 832, 438,1331, 806}, + { 832, 409,1331, 806}, + { 832, 518,1331, 806}, /* 640x480 */ + {1050, 638,1344, 806}, /* 800x600 */ + {1344, 806,1344, 806}, /* 1024x768 */ +}; + +static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_2[]= +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, +}; + +static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_1[]= +{ + { 928, 416, 1688,1066}, + { 928, 366, 1688,1066}, + { 928, 416, 1688,1066}, + { 928, 366, 1688,1066}, + { 928, 496, 1688,1066}, + {1088, 616, 1688,1066}, + {1312, 784, 1688,1066}, + {1568,1040, 1688,1066}, + {1688,1066, 1688,1066} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_2[]= +{ + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, +}; + +static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_1[]= +{ + {1088, 450, 2048,1250}, + {1088, 400, 2048,1250}, + {1088, 450, 2048,1250}, + {1088, 400, 2048,1250}, + {1088, 530, 2048,1250}, + {1248, 650, 2048,1250}, + {1472, 818, 2048,1250}, + {1728,1066, 2048,1250}, + {1848,1066, 2048,1250}, + {2048,1250, 2048,1250} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_2[]= +{ + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250}, + {2048,1250, 2048,1250} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_1[]= +{ + { 768, 438, 1408, 806}, + { 768, 388, 1408, 806}, + { 768, 438, 1408, 806}, + { 768, 388, 1408, 806}, + { 768, 518, 1408, 806}, + { 928, 638, 1408, 806}, + {1152, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_2[]= +{ + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806}, + {1408, 806, 1408, 806} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_1[] = +{ + {840, 604,1344, 800}, + {840, 560,1344, 800}, + {840, 604,1344, 800}, + {840, 560,1344, 800}, + {840, 689,1344, 800}, + {1050, 800,1344, 800}, + {1344, 800,1344, 800}, + {800, 449,1280, 789}, + {800, 525,1280, 785} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_2[] = +{ + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_1[] = +{ + { 840, 438,1344, 806}, + { 840, 409,1344, 806}, + { 840, 438,1344, 806}, + { 840, 409,1344, 806}, + { 840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_2[] = +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +/* TW: Pass 1:1 data */ +static const SiS_LVDSDataStruct SiS_LVDSXXXxXXXData_1[]= +{ + { 800, 449, 800, 449}, + { 800, 449, 800, 449}, + { 900, 449, 900, 449}, + { 900, 449, 900, 449}, + { 800, 525, 800, 525}, /* 640x480 */ + {1056, 628, 1056, 628}, /* 800x600 */ + {1344, 806, 1344, 806}, /* 1024x768 */ + {1344,1066, 1344,1066}, /* 1280x1024 */ /* INSERTED ! */ + {1688, 806, 1688, 806}, /* 1280x768 */ + /* No other panels ! */ +}; + +static const SiS_LVDSDataStruct SiS_LVDS640x480Data_1[]= +{ + { 800, 445, 800, 525}, /* 800, 449, 800, 449 */ + { 800, 395, 800, 525}, + { 800, 445, 800, 525}, + { 800, 395, 800, 525}, + { 800, 525, 800, 525}, + { 800, 525, 800, 525}, /* pseudo */ + { 800, 525, 800, 525} /* pseudo */ +}; + +/* FSTN 320x240 */ +static const SiS_LVDSDataStruct SiS_LVDS640x480Data_2[]= +{ + { 800, 445, 800, 525}, + { 800, 395, 800, 525}, + { 800, 445, 800, 525}, + { 800, 395, 800, 525}, + { 800, 525, 800, 525}, + { 800, 525, 800, 525}, /* pseudo */ + { 800, 525, 800, 525} /* pseudo */ +}; + + +static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_1[]= +{ + { 840, 438,1344, 806}, + { 840, 409,1344, 806}, + { 840, 438,1344, 806}, + { 840, 409,1344, 806}, + { 840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_2[]= +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +static const SiS_LVDSDataStruct SiS_LVDS848x480Data_1[]= +{ + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + {1088, 525,1088, 525}, /* 640x480 TODO */ + {1088, 525,1088, 525}, /* 800x600 TODO */ + {1088, 525,1088, 525}, /* 1024x768 TODO */ + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + {1088, 525,1088, 525}, /* 848x480 */ + {1088, 525,1088, 525} /* 1360x768 TODO */ +}; + +static const SiS_LVDSDataStruct SiS_LVDS848x480Data_2[]= +{ + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + {1088, 525,1088, 525}, /* 640x480 */ + {1088, 525,1088, 525}, /* 800x600 */ + {1088, 525,1088, 525}, /* 1024x768 */ + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + {1088, 525,1088, 525}, /* 848x480 */ + {1088, 525,1088, 525} /* 1360x768 TODO */ +}; + +/* LCDA */ + +static const SiS_LVDSDataStruct SiS_LCDA1400x1050Data_1[]= +{ /* TW: Might be temporary (invalid) data */ + { 928, 416, 1688,1066}, + { 928, 366, 1688,1066}, + {1008, 416, 1688,1066}, + {1008, 366, 1688,1066}, + {1200, 530, 1688,1066}, + {1088, 616, 1688,1066}, + {1312, 784, 1688,1066}, + {1568,1040, 1688,1066}, + {1688,1066, 1688,1066} +}; + +static const SiS_LVDSDataStruct SiS_LCDA1400x1050Data_2[]= +{ /* TW: Temporary data. Not valid */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_1[]= +{ /* TW: Temporary data. Not valid */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + { 800, 449,1280, 801}, + { 800, 525,1280, 813} +}; + +static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_2[]= +{ /* TW: Temporary data. Not valid */ + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + +static const SiS_LVDSDataStruct SiS_CHTVUNTSCData[]= +{ + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 784, 600, 784, 600}, + {1064, 750,1064, 750}, + {1160, 945,1160, 945} +}; + +static const SiS_LVDSDataStruct SiS_CHTVONTSCData[]= +{ + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 784, 525, 784, 525}, + {1040, 700,1040, 700}, + {1160, 840,1160, 840} +}; + +static const SiS_LVDSDesStruct SiS_PanelType1076_1[]= +{ /* 1024x768 */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_PanelType1076_2[]= +{ /* 1024x768 */ + { 1184, 622 }, + { 1184, 597 }, + { 1184, 622 }, + { 1184, 597 }, + { 1152, 622 }, + { 1232, 722 }, + { 0, 0 }, + { 0, 794 }, + { 0, 0 } +}; + +static const SiS_LVDSDesStruct SiS_PanelType1210_1[]= +{ /* 1280x1024 */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_PanelType1210_2[]= +{ /* 1280x1024 */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_PanelType1296_1[]= +{ /* 1400x1050 */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_PanelType1296_2[]= +{ /* 1400x1050 - looks heavily invalid */ + { 808 , 740}, + { 0 , 715}, + { 632 , 740}, + { 632 , 715}, + { 1307, 780}, + { 1387,1157}, + { 1499, 924}, + { 1627,1052}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_PanelType1600_1[]= +{ /* 1600x1200 */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_PanelType1600_2[]= +{ /* 1600x1200 - BIOS looks heavily invalid, not copied */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_PanelTypeNS_1[]= +{ + { 8, 0}, + { 8, 0}, + { 8, 0}, + { 8, 0}, + { 8, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 806}, + { 0, 0 } +}; + +static const SiS_LVDSDesStruct SiS_PanelTypeNS_2[] = +{ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS_LVDSDesStruct SiS_CHTVUNTSCDesData[]= +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS_LVDSDesStruct SiS_CHTVONTSCDesData[]= +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS_LVDSDesStruct SiS_CHTVUPALDesData[]= +{ + {256, 0}, + {256, 0}, + {256, 0}, + {256, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS_LVDSDesStruct SiS_CHTVOPALDesData[]= +{ + {256, 0}, + {256, 0}, + {256, 0}, + {256, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1320x480_1[] = +{ + {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00 }}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01 }}, + {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00 }} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1[] = +{ + {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, + 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, + 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, + 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, + 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba, + 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01, + 0x00}}, + {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1, + 0xae,0x85,0x57,0x1f,0x30,0x00,0x26, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1, + 0xae,0x85,0x57,0x1f,0x30,0x00,0x02, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1_H[] = +{ + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1[] = +{ + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, + 0x00}}, + {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1_H[] = +{ + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1[] = +{ + {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f, + 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01, + 0x00}}, + {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f, + 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01, + 0x00}}, + {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f, + 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01, + 0x00}}, + {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f, + 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01, + 0x00}}, + {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e, + 0xec,0x8e,0xdf,0x05,0x20,0x00,0x01, + 0x00}}, + {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0, + 0x64,0x86,0x57,0x7d,0x20,0x00,0x05, + 0x01}}, + {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5, + 0x0c,0x8e,0xff,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5, + 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06, + 0x01}}, + {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5, + 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1_H[] = +{ + {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, + 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f, + 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f, + 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0, + 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01, + 0x01}}, + {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5, + 0x02,0x86,0xff,0x0f,0x10,0x00,0x01, + 0x01}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a, + 0x02,0x86,0xff,0x0f,0x09,0x00,0x05, + 0x01}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a, + 0x02,0x86,0xff,0x0f,0x09,0x00,0x05, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2[] = +{ + {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb, + 0x54,0x86,0xdb,0xda,0x00,0x00,0x02, + 0x00}}, + {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb, + 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02, + 0x00}}, + {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb, + 0x54,0x86,0xdb,0xda,0x00,0x00,0x02, + 0x00}}, + {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb, + 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02, + 0x00}}, + {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3, + 0x7c,0x8e,0x03,0x02,0x10,0x00,0x02, + 0x01}}, + {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1, + 0xb6,0x88,0x57,0x25,0x10,0x00,0x02, + 0x01}}, + {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5, + 0x0a,0x8c,0xff,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5, + 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06, + 0x01}}, + {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5, + 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2_H[] = +{ + {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, + 0x54,0x86,0xdb,0xda,0x00,0x00,0x01, + 0x00}}, + {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, + 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01, + 0x00}}, + {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, + 0x54,0x86,0xdb,0xda,0x00,0x00,0x01, + 0x00}}, + {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, + 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01, + 0x00}}, + {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3, + 0x7c,0x8e,0x03,0x02,0x10,0x00,0x01, + 0x01}}, + {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1, + 0xb6,0x88,0x57,0x25,0x10,0x00,0x01, + 0x01}}, + {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5, + 0x0a,0x8c,0xff,0x25,0x30,0x00,0x01, + 0x01}}, + {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5, + 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06, + 0x01}}, + {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5, + 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1XXXxXXX_1[] = +{ + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}}, + {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a, + 0x00,0x84,0xff,0x29,0x09,0x00,0x07, + 0x01}}, + {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x07, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1XXXxXXX_1_H[] = +{ + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00}}, + {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x01, + 0x01}}, + {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1[] = +{ + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1_H[] = +{ + {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00, + 0x00}}, + {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x83,0x85,0x63,0xba,0x00,0x00,0x00, + 0x00}}, + {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00, + 0x00}}, + {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x83,0x85,0x63,0xba,0x00,0x00,0x00, + 0x00}}, + {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2[] = +{ + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, + 0x00}}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01}}, + {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2_H[] = +{ + {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00}}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00}}, + {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00}}, + {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00}}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01}}, + {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3[] = +{ + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01}}, + {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3_H[] = +{ + {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00}}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00}}, + {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00}}, + {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00}}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01}}, + {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00}} +}; + +#define SIS_PL_HSYNCP 0x01 +#define SIS_PL_HSYNCN 0x02 +#define SIS_PL_VSYNCP 0x04 +#define SIS_PL_VSYNCN 0x08 +#define SIS_PL_DVI 0x80 + +typedef struct _SiS_PlasmaModes +{ + const char *name; + ULONG clock; + USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth; + USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth; + UCHAR SyncFlags; +} SiS_PlasmaModes; + + +typedef struct _SiS_PlasmaTables +{ + USHORT vendor; + UCHAR productnum; + USHORT product[5]; + const char *plasmaname; + UCHAR modenum; + UCHAR plasmamodes[20]; /* | 0x80 = DVI-capable, | 0x40 = analog */ +} SiS_PlasmaTables; + +static const SiS_PlasmaModes SiS_PlasmaMode[] = { + { "640x400", /* 00: IBM 400@70 */ + 25175, + 640, 800, 17, 64, + 400, 449, 13, 2, + SIS_PL_HSYNCN | SIS_PL_VSYNCN }, + { "640x480", /* 01: VESA 480@72 */ + 31500, + 640, 832, 24, 40, + 480, 520, 9, 3, + SIS_PL_HSYNCN | SIS_PL_VSYNCN }, + { "800x600", /* 02: VESA 600@72 */ + 50000, + 800, 1040, 56, 120, + 600, 666, 37, 6, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "864x480", /* 03: Cereb wide 1 */ + 42526, + 864, 1134, 22, 86, + 480, 500, 1, 3, + SIS_PL_HSYNCP | SIS_PL_VSYNCN }, + { "848x480", /* 04: VESA wide (NEC1) */ + 33750, + 848, 1088, 16, 112, + 480, 517, 6, 8, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1024x576", /* 05: VESA wide (NEC2) */ + 47250, + 1024, 1320, 16, 144, + 576, 596, 2, 4, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1280x720", /* 06: VESA wide (NEC3) */ + 76500, + 1280, 1696, 48, 176, + 720, 750, 4, 8, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1360x765", /* 07: VESA wide (NEC4) */ + 85500, + 1360, 1792, 64, 176, + 765, 795, 4, 8, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1024x600", /* 08: CEREB wide 2 */ + 51200, + 1024, 1352, 51, 164, + 600, 628, 1, 4, + SIS_PL_HSYNCN | SIS_PL_VSYNCP }, + { "1024x768", /* 09: VESA 768@75 */ + 78750, + 1024, 1312, 16, 96, + 768, 800, 1, 3, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1152x864", /* 10: VESA 1152x864@75 */ + 108000, + 1152, 1600, 64, 128, + 864, 900, 1, 3, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1280x1024", /* 11: VESA 1024@60 */ + 108000, + 1280, 1688, 48, 112, + 1024, 1066, 1, 3, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1280x768", /* 12: W_XGA */ + 81000, + 1280, 1688, 48, 112, + 768, 802, 3, 6, + SIS_PL_HSYNCP | SIS_PL_VSYNCN }, + { "1280x768", /* 13: I/O Data W_XGA@56Hz */ + 76064, + 1280, 1688, 48, 112, + 768, 802, 2, 3, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1376x768", /* 14: I/O Wide XGA */ + 87340, + 1376, 1808, 32, 128, + 768, 806, 3, 6, + SIS_PL_HSYNCN | SIS_PL_VSYNCP }, + { "1280x960", /* 15: VESA 960@60 */ + 108000, + 1280, 1800, 96, 112, + 960, 1000, 1, 3, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "1400x1050", /* 16: VESA 1050@60Hz */ + 108000, + 1400, 1688, 48, 112, + 1050, 1066, 1, 3, + SIS_PL_HSYNCN | SIS_PL_VSYNCN }, + { "1360x768", /* 17: VESA wide (NEC4/2) */ + 85500, + 1360, 1792, 64, 112, + 765, 795, 3, 6, + SIS_PL_HSYNCP | SIS_PL_VSYNCP }, + { "800x600", /* 18: VESA 600@56 */ + 36000, + 800, 1024, 24, 2, + 600, 625, 1, 2, + SIS_PL_HSYNCP | SIS_PL_VSYNCP } +}; + +static const SiS_PlasmaTables SiS_PlasmaTable[] = { +#if 0 /* Product IDs missing */ + { 0x38a3, 4, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG", + 14, /* All DVI, except 0, 7, 13; 3, 15, 16 unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,12|0xc0, + 13|0x40,14|0xc0,15|0xc0,16|0xc0, 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 3, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 42PD1/50PD1/50PD2", + 5, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 1, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 42PD3", + 10, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 2, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 42VM3/61XM1", + 11, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0, + 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 2, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 42MP1/42MP2", + 6, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 1, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 50MP1", + 10, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, +#endif + { 0x38a3, 4, + { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1", + 11, /* All DVI except 0, 7, 13, 17 */ + { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0, + 17|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, +#if 0 /* Product IDs missing */ + { 0x38a3, 1, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 3300W", + 3, + { 0|0x40, 1|0xc0,18|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 1, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 4200W", + 4, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 1, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 4210W", + 6, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x38a3, 1, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + "NEC PlasmaSync 5000W", + 7, /* DVI entirely unknown */ + { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, +#endif + { 0x412f, 2, + { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 }, + "Pioneer 503CMX/PDA-5002", + 6, /* DVI unknown */ + { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x34a9, 1, + { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 }, + "Panasonic TH-42", + 5, /* No DVI output */ + { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, + { 0x0000 } +}; + void SiS_SetReg1(USHORT, USHORT, USHORT); void SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT); void SiS_SetReg3(USHORT, USHORT); @@ -153,6 +2398,7 @@ void SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_I void SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo); void SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); +void SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); #ifdef SIS300 void SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); @@ -187,12 +2433,15 @@ void SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr); void SiS_HandleCRT1(SiS_Private *SiS_Pr); void SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo); -void SiS_SetEnableDstn(SiS_Private *SiS_Pr); +void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable); +void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable); void SiS_Delay15us(SiS_Private *SiS_Pr); BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex); BOOLEAN SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,USHORT ModeIdIndex); UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex); +void SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr); +void SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); void SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex); void SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex); void SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, @@ -256,33 +2505,32 @@ void SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtensio void SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr); #ifdef LINUX_XF86 -USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode); -USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags); USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags); void SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr); void SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr); void SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr); -unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id); -unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value); extern int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div, int *out_sbit, int *out_scale); +extern void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk); + +extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value); +extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id); +extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN hcm); #endif extern USHORT SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); extern USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); extern void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); -extern BOOLEAN SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, - PSIS_HW_DEVICE_INFO HwDeviceExtension); -extern void SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4, - PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension); extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr); extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr); extern BOOLEAN SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr); extern BOOLEAN SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO ); extern void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode); -extern BOOLEAN SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, +extern void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension); extern void SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); extern USHORT SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex, @@ -312,5 +2560,18 @@ extern BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceE extern BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); extern USHORT SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +#ifdef LINUX_KERNEL +int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + unsigned char modeno, unsigned char rateindex); +int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + unsigned char modeno, unsigned char rateindex, + ULONG *left_margin, ULONG *right_margin, + ULONG *upper_margin, ULONG *lower_margin, + ULONG *hsync_len, ULONG *vsync_len, + ULONG *sync, ULONG *vmode); +BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex); +#endif + #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c new file mode 100644 index 000000000..2c245fc46 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c @@ -0,0 +1,12408 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.22 2003/08/07 15:04:41 twini Exp $ */ +/* + * Mode switching code (CRT2 section) + * for SiS 300/305/540/630/730/315/550/650/M650/651/740/330/660/M660/760/M760 + * (Universal module for Linux kernel framebuffer and XFree86 4.x) + * + * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net> + * Formerly based on non-functional code-fragements for 300 series by SiS, Inc. + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * TW says: This code looks awful, I know. But please don't do anything about + * this otherwise debugging will be hell. + * The code is extremely fragile as regards the different chipsets, different + * video bridges and combinations thereof. If anything is changed, extreme + * care has to be taken that that change doesn't break it for other chipsets, + * bridges or combinations thereof. + * All comments in this file are by me, regardless if they are marked TW or not. + * + */ + +#if 1 +#define NEWCH701x +#endif + +#include "init301.h" + +#if 0 +#define TWNEWPANEL +#endif + +#ifdef SIS300 +#include "oem300.h" +#endif + +#ifdef SIS315H +#include "oem310.h" +#endif + +#define SiS_I2CDELAY 1000 +#define SiS_I2CDELAYSHORT 150 + +BOOLEAN +SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT ModeIdIndex; + USHORT RefreshRateTableIndex; + + SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; + + if(!SiS_Pr->UseCustomMode) { + SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex); + } else { + ModeIdIndex = 0; + } + + /* Used for shifting CR33 */ + SiS_Pr->SiS_SelectCRT2Rate = 4; + + SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); + + RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + + SiS_SaveCRT2Info(SiS_Pr,ModeNo); + + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr); + if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType == SIS_730)) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x80); + } + SiS_SetCRT2ModeRegs(SiS_Pr,BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + } + + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { + SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); + SiS_DisplayOn(SiS_Pr); + return(TRUE); + } + + SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + + /* Set up Panel Link for LVDS, 301BDH and 650/30xLV(for LCDA) */ + if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || + ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) || + ((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) { + SiS_GetLVDSDesData(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + } else { + SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; + } + +#ifdef LINUX_XF86 +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES); + xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE); + xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE); + xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT); + xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT); +#endif +#endif + + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + SiS_SetGroup1(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension,RefreshRateTableIndex); + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + + SiS_SetGroup2(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + SiS_SetGroup3(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension); + SiS_SetGroup4(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr, + ModeNo,ModeIdIndex); + + /* For 301BDH (Panel link initialization): */ + if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + } + } + } + SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + } + } + + } else { + + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { + SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + } + } + + SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { +#ifdef SIS315H + SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr); +#endif + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + SiS_SetCHTVReg(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex); + } + } + } + + } + +#ifdef SIS300 + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + if(SiS_Pr->SiS_UseOEM) { + if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) { + if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { + SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex); + } + } else { + SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex); + } + } + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || + (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { + SetOEMLCDData2(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo, + ModeIdIndex,RefreshRateTableIndex); + } + if(HwDeviceExtension->jChipType == SIS_730) { + SiS_DisplayOn(SiS_Pr); + } + } + } + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(HwDeviceExtension->jChipType != SIS_730) { + SiS_DisplayOn(SiS_Pr); + } + } + } +#endif + +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension); + if(SiS_Pr->SiS_UseOEM) { + SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex); + } + SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr); + } + } +#endif + + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr); + } + + SiS_DisplayOn(SiS_Pr); + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + /* Disable LCD panel when using TV */ + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C); + } else { + /* Disable TV when using LCD */ + SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8); + } + } + + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); + } + + return 1; +} + +BOOLEAN +SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp,temp1,temp2; + + if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12)) + return(1); + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11); + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80); + temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,0x55); + temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,temp1); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,temp); + if((HwDeviceExtension->jChipType >= SIS_315H) || + (HwDeviceExtension->jChipType == SIS_300)) { + if(temp2 == 0x55) return(0); + else return(1); + } else { + if(temp2 != 0x55) return(1); + else { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); + return(0); + } + } +} + +/* Set Part1 registers */ +void +SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT RefreshRateTableIndex) +{ + USHORT temp=0, tempax=0, tempbx=0, tempcx=0; + USHORT pushbx=0, CRT1Index=0; +#ifdef SIS315H + USHORT tempbl=0; +#endif + USHORT modeflag, resinfo=0; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { +#ifdef SIS315H + SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo, + RefreshRateTableIndex,HwDeviceExtension); + + SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension,RefreshRateTableIndex); +#endif + } else { + + if( (HwDeviceExtension->jChipType >= SIS_315H) && + (SiS_Pr->SiS_IF_DEF_LVDS == 1) && + (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) { + + SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo, + RefreshRateTableIndex,HwDeviceExtension); + + } else { + + SiS_SetCRT2Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + + if (HwDeviceExtension->jChipType < SIS_315H ) { +#ifdef SIS300 + SiS_SetCRT2FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension); +#endif + } else { +#ifdef SIS315H + SiS_SetCRT2FIFO_310(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension); +#endif + } + + SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo, + RefreshRateTableIndex,HwDeviceExtension); + + /* 1. Horizontal setup */ + + if (HwDeviceExtension->jChipType < SIS_315H ) { + +#ifdef SIS300 /* ------------- 300 series --------------*/ + + temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ + + temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */ + + temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */ + + pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA@HRS 0x0B,0x0C */ + tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2; + tempbx = pushbx + tempcx; + tempcx <<= 1; + tempcx += tempbx; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->UseCustomMode) { + tempbx = SiS_Pr->CHSyncStart + 12; + tempcx = SiS_Pr->CHSyncEnd + 12; + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { + unsigned char cr4, cr14, cr5, cr15; + if(SiS_Pr->UseCustomMode) { + cr4 = SiS_Pr->CCRT1CRTC[4]; + cr14 = SiS_Pr->CCRT1CRTC[14]; + cr5 = SiS_Pr->CCRT1CRTC[5]; + cr15 = SiS_Pr->CCRT1CRTC[15]; + } else { + cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4]; + cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14]; + cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5]; + cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15]; + } + tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3; + tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3; + } + + if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){ + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){ + tempbx = 1040; + tempcx = 1042; + } + } + } + + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* CRT2 Horizontal Retrace Start */ +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* ------------------- 315/330 series --------------- */ + + tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */ + if(modeflag & HalfDCLK) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + tempax = SiS_Pr->SiS_VGAHDE >> 1; + tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + tempcx = SiS_Pr->SiS_HT - tempax; + } + } else { + tempcx >>= 1; + } + } + tempcx--; + + temp = tempcx & 0xff; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ + + temp = ((tempcx & 0xff00) >> 8) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */ + + tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */ + tempbx = SiS_Pr->SiS_VGAHDE; + tempcx -= tempbx; + tempcx >>= 2; + if(modeflag & HalfDCLK) { + tempbx >>= 1; + tempcx >>= 1; + } + tempbx += 16; + + temp = tempbx & 0xff; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */ + + pushbx = tempbx; + tempcx >>= 1; + tempbx += tempcx; + tempcx += tempbx; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->UseCustomMode) { + tempbx = SiS_Pr->CHSyncStart + 16; + tempcx = SiS_Pr->CHSyncEnd + 16; + tempax = SiS_Pr->SiS_VGAHT; + if(modeflag & HalfDCLK) tempax >>= 1; + tempax--; + if(tempcx > tempax) tempcx = tempax; + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { + unsigned char cr4, cr14, cr5, cr15; + if(SiS_Pr->UseCustomMode) { + cr4 = SiS_Pr->CCRT1CRTC[4]; + cr14 = SiS_Pr->CCRT1CRTC[14]; + cr5 = SiS_Pr->CCRT1CRTC[5]; + cr15 = SiS_Pr->CCRT1CRTC[15]; + } else { + cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4]; + cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14]; + cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5]; + cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15]; + } + tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */ + tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */ + tempcx &= 0x00FF; + tempcx |= (tempbx & 0xFF00); + tempbx += 16; + tempcx += 16; + tempax = SiS_Pr->SiS_VGAHT; + if(modeflag & HalfDCLK) tempax >>= 1; + tempax--; + if(tempcx > tempax) tempcx = tempax; + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if(resinfo == SIS_RI_1024x768) { + tempbx = 1040; + tempcx = 1042; + } + } + } +#if 0 + /* Makes no sense, but is in 650/30xLV 1.10.6s */ + if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){ + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + tempbx = 1040; + tempcx = 1042; + } + } + } +#endif + } + + temp = tempbx & 0xff; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* CRT2 Horizontal Retrace Start */ +#endif /* SIS315H */ + + } /* 315/330 series */ + + /* The following is done for all bridge/chip types/series */ + + tempax = tempbx & 0xFF00; + tempbx = pushbx; + tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4); + tempax |= (tempbx & 0xFF00); + temp = (tempax & 0xFF00) >> 8; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */ + + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp); /* CRT2 Horizontal Retrace End */ + + /* 2. Vertical setup */ + + tempcx = SiS_Pr->SiS_VGAVT - 1; + temp = tempcx & 0x00FF; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { + temp--; + } + } + } else { + temp--; + } + } else if(HwDeviceExtension->jChipType >= SIS_315H) { + /* 650/30xLV 1.10.6s */ + temp--; + } + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */ + + tempbx = SiS_Pr->SiS_VGAVDE - 1; + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp); /* CRT2 Vertical Display Enable End */ + + temp = ((tempbx & 0xFF00) << 3) >> 8; + temp |= ((tempcx & 0xFF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow (and HWCursor Test Mode) */ + + /* 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + tempbx++; + tempax = tempbx; + tempcx++; + tempcx -= tempax; + tempcx >>= 2; + tempbx += tempcx; + if(tempcx < 4) tempcx = 4; + tempcx >>= 2; + tempcx += tempbx; + tempcx++; + } else { + /* 300 series, LVDS/301B: */ + tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */ + tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */ + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->UseCustomMode) { + tempbx = SiS_Pr->CVSyncStart; + tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF); + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { + unsigned char cr8, cr7, cr13, cr9; + if(SiS_Pr->UseCustomMode) { + cr8 = SiS_Pr->CCRT1CRTC[8]; + cr7 = SiS_Pr->CCRT1CRTC[7]; + cr13 = SiS_Pr->CCRT1CRTC[13]; + cr9 = SiS_Pr->CCRT1CRTC[9]; + } else { + cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8]; + cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7]; + cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13]; + cr9 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9]; + } + tempbx = cr8; + if(cr7 & 0x04) tempbx |= 0x0100; + if(cr7 & 0x80) tempbx |= 0x0200; + if(cr13 & 0x08) tempbx |= 0x0400; + tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF); + } + } + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); /* CRT2 Vertical Retrace Start */ + + temp = ((tempbx & 0xFF00) >> 8) << 4; + temp |= (tempcx & 0x000F); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */ + + /* 3. Panel compensation delay */ + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* ---------- 300 series -------------- */ + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + temp = 0x20; + + if(HwDeviceExtension->jChipType == SIS_300) { + temp = 0x10; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20; + } + if(SiS_Pr->SiS_VBType & VB_SIS301) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20; + } + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) temp = 0x2c; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c; + else temp = 0x20; + } + if((ROMAddr) && (SiS_Pr->SiS_UseROM)) { + if(ROMAddr[0x220] & 0x80) { + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV)) + temp = ROMAddr[0x221]; + else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) + temp = ROMAddr[0x222]; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) + temp = ROMAddr[0x223]; + else + temp = ROMAddr[0x224]; + temp &= 0x3c; + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(HwDeviceExtension->pdc) { + temp = HwDeviceExtension->pdc & 0x3c; + } + } + } else { + temp = 0x20; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04; + } + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(ROMAddr[0x220] & 0x80) { + temp = ROMAddr[0x220] & 0x3c; + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(HwDeviceExtension->pdc) { + temp = HwDeviceExtension->pdc & 0x3c; + } + } + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */ + +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* --------------- 315/330 series ---------------*/ + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + temp = 0x10; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) temp = 0x2c; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + temp = 0x08; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + switch(SiS_Pr->SiS_HiVision) { + case 2: + case 1: + case 0: + temp = 0x08; + break; + default: + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c; + else temp = 0x20; + } + } + } + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { + tempbl = 0x00; + if((ROMAddr) && (SiS_Pr->SiS_UseROM)) { + if(HwDeviceExtension->jChipType < SIS_330) { + if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0; + } else { + if(ROMAddr[0x1bc] & 0x80) tempbl = 0xf0; + } + } + } else { /* LV (550/301LV checks ROM byte, other LV BIOSes do not) */ + tempbl = 0xF0; + } + } else { + if(HwDeviceExtension->jChipType == SIS_740) { + temp = 0x03; + } else { + temp = 0x00; + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a; + tempbl = 0xF0; + if(HwDeviceExtension->jChipType == SIS_650) { + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F; + } + } + + if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) { + temp = 0x08; + tempbl = 0; + if((ROMAddr) && (SiS_Pr->SiS_UseROM)) { + if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0; + } + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */ + + tempax = 0; + if (modeflag & DoubleScanMode) tempax |= 0x80; + if (modeflag & HalfDCLK) tempax |= 0x40; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax); + +#endif /* SIS315H */ + + } + + } /* Slavemode */ + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + /* For 301BDH with LCD, we set up the Panel Link */ + if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) { + + SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension,RefreshRateTableIndex); + + } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + + SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension,RefreshRateTableIndex); + } + + } else { + + if(HwDeviceExtension->jChipType < SIS_315H) { + + SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension,RefreshRateTableIndex); + } else { + + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension,RefreshRateTableIndex); + } + } else { + SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + HwDeviceExtension,RefreshRateTableIndex); + } + + } + + } + } /* LCDA */ +} + +void +SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex) +{ + USHORT push1,push2; + USHORT tempax,tempbx,tempcx,temp; + USHORT resinfo,modeflag; + unsigned char p1_7, p1_8; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + resinfo = 0; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + } + + /* The following is only done if bridge is in slave mode: */ + + tempax = 0xFFFF; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr); + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot; + + if(modeflag & Charx8Dot) tempcx = 0x08; + else tempcx = 0x09; + + if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT; + + if(modeflag & HalfDCLK) tempax >>= 1; + + tempax = (tempax / tempcx) - 5; + tempbx = tempax & 0x00FF; + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */ + + tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */ + if(modeflag & HalfDCLK) tempax >>= 1; + tempax = (tempax / tempcx) - 1; + tempbx |= ((tempax & 0x00FF) << 8); + temp = tempax & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,temp); + + temp = (tempbx & 0xFF00) >> 8; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) { + temp += 2; + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + if(SiS_Pr->SiS_HiVision == 3) { + if(resinfo == SIS_RI_800x600) temp -= 2; + } + } + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */ + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */ + + if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (SiS_Pr->SiS_HiVision == 3)) { + temp = (tempbx & 0x00FF) - 1; + if(!(modeflag & HalfDCLK)) { + temp -= 6; + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + temp -= 2; + if(ModeNo > 0x13) temp -= 10; + } + } + } else { + tempcx = tempbx & 0x00FF; + tempbx = (tempbx & 0xFF00) >> 8; + tempcx = (tempcx + tempbx) >> 1; + temp = (tempcx & 0x00FF) + 2; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + temp--; + if(!(modeflag & HalfDCLK)) { + if((modeflag & Charx8Dot)) { + temp += 4; + if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VGAHDE == 800) temp += 2; + } + } + } + } else { + if(!(modeflag & HalfDCLK)) { + temp -= 4; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) { + if(SiS_Pr->SiS_VGAHDE >= 800) { + temp -= 7; + if(HwDeviceExtension->jChipType < SIS_315H) { + /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */ + if(SiS_Pr->SiS_ModeType == ModeEGA) { + if(SiS_Pr->SiS_VGAVDE == 1024) { + temp += 15; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) + temp += 7; + } + } + } + if(SiS_Pr->SiS_VGAHDE >= 1280) { + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28; + } + } + } + } + } + } + + p1_7 = temp; + p1_8 = 0x00; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + if(ModeNo <= 0x01) { + p1_7 = 0x2a; + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_8 = 0x61; + else p1_8 = 0x41; + } else if(SiS_Pr->SiS_ModeType == ModeText) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_7 = 0x54; + else p1_7 = 0x55; + p1_8 = 0x00; + } else if(ModeNo <= 0x13) { + if(modeflag & HalfDCLK) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + p1_7 = 0x30; + p1_8 = 0x03; + } else { + p1_7 = 0x2f; + p1_8 = 0x02; + } + } else { + p1_7 = 0x5b; + p1_8 = 0x03; + } + } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && + ((ModeNo == 0x50) || (ModeNo = 0x56) || (ModeNo = 0x53))) || + ((HwDeviceExtension->jChipType < SIS_315H) && + (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + p1_7 = 0x30, + p1_8 = 0x03; + } else { + p1_7 = 0x2f; + p1_8 = 0x03; + } + } + } + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + if(SiS_Pr->SiS_HiVision & 0x03) { + p1_7 = 0xb2; + if(SiS_Pr->SiS_HiVision & 0x02) { + p1_7 = 0xab; + } + } + } + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */ + + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */ + + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0); + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */ + + tempcx = 0x121; + tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */ + if (tempbx == 357) tempbx = 350; + else if(tempbx == 360) tempbx = 350; + else if(tempbx == 375) tempbx = 350; + else if(tempbx == 405) tempbx = 400; + else if(tempbx == 420) tempbx = 400; + else if(tempbx == 525) tempbx = 480; + push2 = tempbx; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { + if (tempbx == 350) tempbx += 5; + else if(tempbx == 480) tempbx += 5; + } + } + } + tempbx -= 2; + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */ + + tempbx = push2; + tempbx--; + temp = tempbx & 0x00FF; +#if 0 + /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */ + if(xxx()) { + if(temp == 0xdf) temp = 0xda; + } +#endif + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp); + + if(tempbx & 0x0100) tempcx |= 0x0002; + + tempax = 0x000B; + if(modeflag & DoubleScanMode) tempax |= 0x8000; + + if(tempbx & 0x0200) tempcx |= 0x0040; + + temp = (tempax & 0xFF00) >> 8; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); + + if(tempbx & 0x0400) tempcx |= 0x0600; + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */ + + tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2; + + if((ModeNo > 0x13) || (HwDeviceExtension->jChipType < SIS_315H)) { + if(resinfo != SIS_RI_1280x1024) { + tempbx += (tempax << 1); + } + } else if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) { + tempbx += (tempax << 1); + } + } + + if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (SiS_Pr->SiS_HiVision == 3)) { + tempbx -= 10; + } else { + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + if(!(SiS_Pr->SiS_HiVision & 0x03)) { + tempbx += 40; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10; + } + } + } + } + } + tempax >>= 2; + tempax++; + tempax += tempbx; + push1 = tempax; + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + if(tempbx <= 513) { + if(tempax >= 513) tempbx = 513; + } + } + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */ + + tempbx--; + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); + + if(tempbx & 0x0100) tempcx |= 0x0008; + + if(tempbx & 0x0200) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20); + } + tempbx++; + + if(tempbx & 0x0100) tempcx |= 0x0004; + if(tempbx & 0x0200) tempcx |= 0x0080; + if(tempbx & 0x0400) { + if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800; + else tempcx |= 0x0C00; + } + + tempbx = push1; + temp = tempbx & 0x000F; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */ + + if(tempbx & 0x0010) tempcx |= 0x2000; + + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */ + + temp = (tempcx & 0xFF00) >> 8; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */ + + tempax = modeflag; + temp = (tempax & 0xFF00) >> 8; + temp = (temp >> 1) & 0x09; + if(!(SiS_Pr->SiS_VBType & VB_SIS301)) { + /* Only use 8 dot clock */ + temp |= 0x01; + } + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */ + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */ + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */ + + if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { + if(IS_SIS650) { + /* 650/30xLV 1.10.6s */ + if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { + temp = 0x80; + } + } else temp = 0x80; + } else temp = 0x00; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */ + +} + +void +SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT RefreshRateTableIndex) +{ + USHORT modeflag, resinfo; + USHORT push1, push2, tempax, tempbx, tempcx, temp; +#ifdef SIS315H + USHORT pushcx; +#endif + ULONG tempeax=0, tempebx, tempecx, tempvcfact=0; + + /* This is not supported on LVDS */ + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return; + if(SiS_Pr->UseCustomMode) return; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + + /* Set up Panel Link */ + + /* 1. Horizontal setup */ + + tempax = SiS_Pr->SiS_LCDHDES; + + if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { + if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) && + (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) { + tempax -= 8; + } + } + + tempcx = SiS_Pr->SiS_HT; /* Horiz. Total */ + + tempbx = SiS_Pr->SiS_HDE; /* Horiz. Display End */ + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) { + tempbx >>= 1; + } + + if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { + tempbx = SiS_Pr->PanelXRes; + } else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + tempbx = SiS_Pr->PanelXRes; + if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { + tempbx = 800; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) { + tempbx = 1024; + } + } + } + } + } + tempcx = (tempcx - tempbx) >> 2; /* HT-HDE / 4 */ + + push1 = tempax; + + tempax += tempbx; + + if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT; + + push2 = tempax; + + if((!SiS_Pr->SiS_IF_DEF_FSTN) && + (!SiS_Pr->SiS_IF_DEF_DSTN) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1366) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1024) && + (SiS_Pr->SiS_CustomT != CUT_PANEL848)) { + if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0028; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0018; + else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) { + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + tempcx = 0x0017; +#ifdef TWNEWPANEL + tempcx = 0x0018; +#endif + } else { + tempcx = 0x0017; /* A901; sometimes 0x0018; */ + } + } else { + tempcx = 0x0018; + } + } + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0028; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040; + } + } + } + } + + tempcx += tempax; /* lcdhrs */ + if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT; + + tempax = tempcx >> 3; /* BPLHRS */ + temp = tempax & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h; Panel Link Horizontal Retrace Start */ + + if(SiS_Pr->SiS_LCDInfo & LCDPass11) { + temp = (tempax & 0x00FF) + 2; + } else { + temp = (tempax & 0x00FF) + 10; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if((!SiS_Pr->SiS_IF_DEF_DSTN) && + (!SiS_Pr->SiS_IF_DEF_FSTN) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1366) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1024) && + (SiS_Pr->SiS_CustomT != CUT_PANEL848)) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + temp += 6; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) { + temp++; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) { + temp += 7; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) { + temp -= 0x14; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768) { + temp -= 10; + } + } + } + } + } + } + } + } + } + + temp &= 0x1F; + temp |= ((tempcx & 0x0007) << 5); +#if 0 + if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */ +#endif + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h; Panel Link Horizontal Retrace End/Skew */ + + tempbx = push2; + tempcx = push1; /* lcdhdes */ + + temp = (tempcx & 0x0007); /* BPLHDESKEW */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */ + + tempcx >>= 3; /* BPLHDES */ + temp = (tempcx & 0x00FF); +#if 0 /* Not 550 FSTN */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(ModeNo == 0x5b) temp--; */ + } +#endif + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h; Panel Link Horizontal Display Enable Start */ + + if((HwDeviceExtension->jChipType < SIS_315H) || + (SiS_Pr->SiS_IF_DEF_FSTN) || + (SiS_Pr->SiS_IF_DEF_DSTN)) { + if(tempbx & 0x07) tempbx += 8; + } + tempbx >>= 3; /* BPLHDEE */ + temp = tempbx & 0x00FF; +#if 0 /* Not 550 FSTN */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(ModeNo == 0x5b) temp--; + } +#endif + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h; Panel Link Horizontal Display Enable End */ + + /* 2. Vertical setup */ + + if(HwDeviceExtension->jChipType < SIS_315H) { + tempcx = SiS_Pr->SiS_VGAVT; + tempbx = SiS_Pr->SiS_VGAVDE; + if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) { + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + tempbx = SiS_Pr->PanelYRes; + } + } + } + tempcx -= tempbx; + + } else { + + tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; /* VGAVT-VGAVDE */ + + } + + tempbx = SiS_Pr->SiS_LCDVDES; /* VGAVDES */ + push1 = tempbx; + + tempax = SiS_Pr->SiS_VGAVDE; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + tempax = 600; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) { + tempax = 768; + } + } + } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0) && + (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) && + ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) || + (SiS_Pr->SiS_IF_DEF_FSTN) || + (SiS_Pr->SiS_IF_DEF_DSTN)) ) { + tempax = SiS_Pr->PanelYRes; + } + } + + tempbx += tempax; + if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; + + push2 = tempbx; + + tempcx >>= 1; + + if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && + (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1366) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1024) && + (SiS_Pr->SiS_CustomT != CUT_PANEL848)) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) { + tempcx = 0x0017; + } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { + if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0003; + else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001; + else tempcx = 0x0057; + } else { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0001; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0001; + else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) { + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + tempcx = 0x0002; +#ifdef TWNEWPANEL + tempcx = 0x0003; +#endif + } else { + tempcx = 0x0002; /* A901; sometimes 0x0003; */ + } + } else tempcx = 0x0003; + } + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0003; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001; + else tempcx = 0x0057; + } + } + } + + tempbx += tempcx; /* BPLVRS */ + + if((HwDeviceExtension->jChipType < SIS_315H) || + (SiS_Pr->SiS_IF_DEF_FSTN) || + (SiS_Pr->SiS_IF_DEF_DSTN)) { + tempbx++; + } + + if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; + + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h; Panel Link Vertical Retrace Start */ + + tempcx >>= 3; + + if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1366) && + (SiS_Pr->SiS_CustomT != CUT_BARCO1024) && + (SiS_Pr->SiS_CustomT != CUT_PANEL848)) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if( (HwDeviceExtension->jChipType < SIS_315H) && + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) ) tempcx = 0x0001; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) tempcx = 0x0002; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempcx = 0x0002; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0003; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0005; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempcx = 0x0005; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0011; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0005; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0002; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0011; + else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + tempcx = 0x0004; +#ifdef TWNEWPANEL + tempcx = 0x0005; +#endif + } else { + tempcx = 0x0004; /* A901; Other BIOS sets 0x0005; */ + } + } else { + tempcx = 0x0005; + } + } + } + } + + tempcx = tempcx + tempbx + 1; /* BPLVRE */ + temp = tempcx & 0x000F; + if(SiS_Pr->SiS_IF_DEF_FSTN || + SiS_Pr->SiS_IF_DEF_DSTN || + (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || + (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || + (SiS_Pr->SiS_CustomT == CUT_PANEL848)) { + temp |= 0x30; + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc. */ + + temp = ((tempbx & 0x0700) >> 8) << 3; /* BPLDESKEW =0 */ + if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { + if(SiS_Pr->SiS_HDE != 640) { + if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; + } + } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; + if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40; + if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { + temp |= 0x80; + } + } else { + if( (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) ) { + if(HwDeviceExtension->jChipRevision >= 0x30) { + temp |= 0x80; + } + } + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */ + + if (HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* 300 series */ + + tempeax = SiS_Pr->SiS_VGAVDE << 6; + temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE); + tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE; + if(temp != 0) tempeax++; + tempebx = tempeax; /* BPLVCFACT */ + + if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) { + tempebx = 0x003F; + } + + temp = (USHORT)(tempebx & 0x00FF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp); /* Part1_1Eh; Panel Link Vertical Scaling Factor */ + +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* 315 series */ + + if(HwDeviceExtension->jChipType == SIS_740) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03); + } else { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23); + } + + tempeax = SiS_Pr->SiS_VGAVDE << 18; + temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE); + tempeax = tempeax / SiS_Pr->SiS_VDE; + if(temp != 0) tempeax++; + tempebx = tempeax; /* BPLVCFACT */ + tempvcfact = tempeax; + temp = (USHORT)(tempebx & 0x00FF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp); /* Part1_37h; Panel Link Vertical Scaling Factor */ + temp = (USHORT)((tempebx & 0x00FF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp); /* Part1_36h; Panel Link Vertical Scaling Factor */ + temp = (USHORT)((tempebx & 0x00030000) >> 16); + temp &= 0x03; + if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp); /* Part1_35h; Panel Link Vertical Scaling Factor */ + +#endif /* SIS315H */ + + } + + tempbx = push2; /* BPLVDEE */ + tempcx = push1; + + push1 = temp; + + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) { + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) { + if(resinfo == SIS_RI_1024x600) tempcx++; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + if(resinfo == SIS_RI_800x600) tempcx++; + } + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) { + if(resinfo == SIS_RI_800x600) tempcx++; + if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */ + } else if(resinfo == SIS_RI_1024x768) tempcx++; + } else { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) { + if(resinfo == SIS_RI_800x600) tempcx++; + } + } + } + } + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { + if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { + tempcx = SiS_Pr->SiS_VGAVDE; + tempbx = SiS_Pr->SiS_VGAVDE - 1; + } + } + + temp = ((tempbx & 0x0700) >> 8) << 3; + temp |= ((tempcx & 0x0700) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh; Vertical Display Overflow; Control Signal */ + + temp = tempbx & 0x00FF; + /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++; */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch; Panel Link Vertical Display Enable End */ + + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh; Panel Link Vertical Display Enable Start */ + + /* 3. Additional horizontal setup (scaling, etc) */ + + tempecx = SiS_Pr->SiS_VGAHDE; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { + if(modeflag & HalfDCLK) tempecx >>= 1; + } + } + tempebx = SiS_Pr->SiS_HDE; + if(tempecx == tempebx) tempeax = 0xFFFF; + else { + tempeax = tempecx; + tempeax <<= 16; + temp = (USHORT)(tempeax % tempebx); + tempeax = tempeax / tempebx; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(temp) tempeax++; + } + } + tempecx = tempeax; + + if(HwDeviceExtension->jChipType >= SIS_315H) { + tempeax = SiS_Pr->SiS_VGAHDE; + if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { + if(modeflag & HalfDCLK) tempeax >>= 1; + } + tempeax <<= 16; + tempeax = (tempeax / tempecx) - 1; + } else { + tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1; + } + tempecx <<= 16; + tempecx |= (tempeax & 0xFFFF); + temp = (USHORT)(tempecx & 0x00FF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */ + + tempbx = SiS_Pr->SiS_VDE; + if(HwDeviceExtension->jChipType >= SIS_315H) { + tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact; + tempbx = (USHORT)(tempeax & 0x0FFFF); + } else { + tempeax = SiS_Pr->SiS_VGAVDE << 6; + tempbx = push1 & 0x3f; + if(tempbx == 0) tempbx = 64; + tempeax /= tempbx; + tempbx = (USHORT)(tempeax & 0x0FFFF); + } + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--; + if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) { + if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1; + else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempbx = 1; + } + + temp = ((tempbx & 0xFF00) >> 8) << 3; + temp |= (USHORT)((tempecx & 0x0700) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h; Overflow register */ + + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h; Panel Link Vertical Accumulator Register */ + + tempecx >>= 16; /* BPLHCFACT */ + if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) { + if(modeflag & HalfDCLK) tempecx >>= 1; + } + temp = (USHORT)((tempecx & 0xFF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h; Panel Link Horizontal Scaling Factor High */ + + temp = (USHORT)(tempecx & 0x00FF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp); /* Part1_22h; Panel Link Horizontal Scaling Factor Low */ + + /* 630/301B and 630/LVDS do something for 640x480 panels here */ + +#ifdef SIS315H + if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B); + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03); + tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */ + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1; + tempax += 64; + temp = tempax & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp); + temp = ((tempax & 0xFF00) >> 8) << 3; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp); + tempax += 32; /* Blpe=lBlps+32 */ + temp = tempax & 0x00FF; + if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */ + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00); + + tempax = SiS_Pr->SiS_VDE; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1; + tempax >>= 1; + temp = tempax & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp); + temp = ((tempax & 0xFF00) >> 8) << 3; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp); + + tempeax = SiS_Pr->SiS_HDE; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1; + tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */ + tempebx = 128; + temp = (USHORT)(tempeax % tempebx); + tempeax = tempeax / tempebx; + if(temp) tempeax++; + temp = (USHORT)(tempeax & 0x003F); + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10); + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00); + + tempax = SiS_Pr->SiS_HDE; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1; + tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */ + pushcx = tempax; + temp = tempax & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp); + temp = ((tempax & 0xFF00) >> 8) << 3; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp); + + tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */ + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1; + tempeax = (tempax * pushcx); + tempebx = 0x00100000 + tempeax; + temp = (USHORT)tempebx & 0x000000FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp); + temp = (USHORT)((tempebx & 0x0000FF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp); + temp = (USHORT)((tempebx & 0x00FF0000) >> 16); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp); + temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7); + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp); + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0x38); + + if(SiS_Pr->SiS_IF_DEF_FSTN) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,0x0c); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,0x80); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,0xA0); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3a,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3b,0xf0); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3c,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3d,0x10); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3e,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3f,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,0x10); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,0x25); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,0x80); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,0x14); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x44,0x03); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x45,0x0a); + } + } +#endif /* SIS315H */ + +} + +#ifdef SIS315H +void +SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr) +{ + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40); +} +#endif + + +#ifdef SIS315H +/* For LVDS / 302B/30xLV - LCDA (this must only be called on 315 series!) */ +void +SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex) +{ + USHORT modeflag,resinfo; + USHORT push1,push2,tempax,tempbx,tempcx,temp; + ULONG tempeax=0,tempebx,tempecx,tempvcfact; + + /* This is not supported with LCDA */ + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return; + if(SiS_Pr->UseCustomMode) return; + + if(IS_SIS330) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); /* Xabre 1.01.03 */ + } else if(IS_SIS740) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 740/LVDS */ + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); /* 740/LVDS */ + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03); + } else { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); /* 740/301LV, 301BDH */ + } + } else { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 650/LVDS */ + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); /* 650/LVDS */ + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00); /* 650/LVDS 1.10.07 */ + } else { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f); /* 650/30xLv 1.10.6s */ + } + } + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + + tempax = SiS_Pr->SiS_LCDHDES; + tempbx = SiS_Pr->SiS_HDE; + tempcx = SiS_Pr->SiS_HT; + + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + tempbx = SiS_Pr->PanelXRes; + } + tempcx -= tempbx; /* HT-HDE */ + push1 = tempax; + tempax += tempbx; /* lcdhdee */ + tempbx = SiS_Pr->SiS_HT; + if(tempax >= tempbx) tempax -= tempbx; + + push2 = tempax; /* push ax lcdhdee */ + + tempcx >>= 2; + + /* 650/30xLV 1.10.6s, 740/LVDS */ + if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) || + ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x28; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 0x18; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x40; + else tempcx = 0x30; + } + } + + tempcx += tempax; /* lcdhrs */ + if(tempcx >= tempbx) tempcx -= tempbx; + /* v ah,cl */ + tempax = tempcx; + tempax >>= 3; /* BPLHRS */ + temp = tempax & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h */ + + temp += 10; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + temp += 6; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) { + temp++; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) { + temp += 7; + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) { + temp -= 10; + } + } + } + } + } + } + temp &= 0x1F; + temp |= ((tempcx & 0x07) << 5); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h */ + + tempbx = push2; /* lcdhdee */ + tempcx = push1; /* lcdhdes */ + temp = (tempcx & 0x00FF); + temp &= 0x07; /* BPLHDESKEW */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah */ + + tempcx >>= 3; /* BPLHDES */ + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h */ + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(tempbx & 0x07) tempbx += 8; + } + tempbx >>= 3; /* BPLHDEE */ + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h */ + + tempcx = SiS_Pr->SiS_VGAVT; + tempbx = SiS_Pr->SiS_VGAVDE; + tempcx -= tempbx; /* GAVT-VGAVDE */ + tempbx = SiS_Pr->SiS_LCDVDES; /* VGAVDES */ + push1 = tempbx; + if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { + tempax = SiS_Pr->PanelYRes; + } else { + tempax = SiS_Pr->SiS_VGAVDE; + } + + tempbx += tempax; + tempax = SiS_Pr->SiS_VT; /* VT */ + if(tempbx >= tempax) tempbx -= tempax; + + push2 = tempbx; + + tempcx >>= 2; + + /* 650/30xLV 1.10.6s, 740/LVDS */ + if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) || + ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 1; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 3; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 3; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 1; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 1; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 1; + else tempcx = 0x0057; + } + } + + tempbx += tempcx; + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + tempbx++; /* BPLVRS */ + } + if(tempbx >= tempax) tempbx -= tempax; + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h */ + + tempcx >>= 3; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 3; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 5; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 5; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 5; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 2; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 2; + } + } + } + tempcx += tempbx; + tempcx++; /* BPLVRE */ + temp = tempcx & 0x00FF; + temp &= 0x0F; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); + } else { + /* 650/30xLV 1.10.6s, Xabre */ + temp |= 0xC0; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* Part1_19h */ + } + + temp = (tempbx & 0xFF00) >> 8; + temp &= 0x07; + temp <<= 3; /* BPLDESKEW =0 */ + tempbx = SiS_Pr->SiS_VGAVDE; + if(tempbx != SiS_Pr->SiS_VDE) temp |= 0x40; + if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { + if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80; + } + } else { + if(IS_SIS650) { + /* 650/30xLV 1.10.6s */ + if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { + if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80; + } + } else { + if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x80; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah */ + + tempbx = push2; /* BPLVDEE */ + tempcx = push1; /* NPLVDES */ + push1 = (USHORT)(tempeax & 0xFFFF); + + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) { + if(resinfo == SIS_RI_800x600) tempcx++; + } + } + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { + tempbx = SiS_Pr->SiS_VGAVDE; + tempcx = tempbx; + tempbx--; + } + + temp = (tempbx & 0xFF00) >> 8; + temp &= 0x07; + temp <<= 3; + temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh */ + + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch */ + + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh */ + + tempecx = SiS_Pr->SiS_VGAVT; + tempebx = SiS_Pr->SiS_VDE; + tempeax = SiS_Pr->SiS_VGAVDE; + tempecx -= tempeax; /* VGAVT-VGAVDE */ + tempeax <<= 18; + temp = (USHORT)(tempeax % tempebx); + tempeax = tempeax / tempebx; + if(temp) tempeax++; + tempebx = tempeax; /* BPLVCFACT */ + tempvcfact = tempeax; + temp = (USHORT)(tempebx & 0x00FF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp); + + temp = (USHORT)((tempebx & 0x00FF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp); + + temp = (USHORT)((tempebx & 0x00030000) >> 16); + if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp); + + tempecx = SiS_Pr->SiS_VGAHDE; + if(modeflag & HalfDCLK) tempecx >>= 1; + tempebx = SiS_Pr->SiS_HDE; + tempeax = tempecx; + tempeax <<= 16; + temp = tempeax % tempebx; + tempeax = tempeax / tempebx; + if(temp) tempeax++; + if(tempebx == tempecx) tempeax = 0xFFFF; + tempecx = tempeax; + tempeax = SiS_Pr->SiS_VGAHDE; + if(modeflag & HalfDCLK) tempeax >>= 1; + tempeax <<= 16; + tempeax = tempeax / tempecx; + tempecx <<= 16; + tempeax--; + tempecx = tempecx | (tempeax & 0xFFFF); + temp = (USHORT)(tempecx & 0x00FF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh */ + + tempeax = SiS_Pr->SiS_VGAVDE; + tempeax <<= 18; + tempeax = tempeax / tempvcfact; + tempbx = (USHORT)(tempeax & 0x0FFFF); + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--; + + if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempbx = 1; + + temp = ((tempbx & 0xFF00) >> 8) << 3; + temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h */ + + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h */ + + tempecx >>= 16; /* BPLHCFACT */ + if(modeflag & HalfDCLK) tempecx >>= 1; + temp = (USHORT)((tempecx & 0x0000FF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h */ + + temp=(USHORT)(tempecx & 0x000000FF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp); + +#if 0 + /* Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */ + if(xxx()) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda); + } +#endif + + /* Only for LVDS and 301LV/302LV */ + if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)){ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20); + } + +} +#endif /* SIS 315 */ + +void SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex ,USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT offset; + UCHAR temp; + + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return; + + offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1; + + temp = (UCHAR)(offset & 0xFF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp); + temp = (UCHAR)((offset & 0xFF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,temp); + temp = (UCHAR)(((offset >> 3) & 0xFF) + 1); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp); +} + +USHORT +SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp,colordepth; + USHORT modeinfo,index,infoflag; + + if(SiS_Pr->UseCustomMode) { + infoflag = SiS_Pr->CInfoFlag; + temp = SiS_Pr->CHDisplay / 16; + } else { + infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo; + index = (modeinfo >> 8) & 0xFF; + temp = SiS_Pr->SiS_ScreenOffset[index]; + } + + colordepth = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex); + + if(infoflag & InterlaceMode) temp <<= 1; + + temp *= colordepth; + + if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) || + ModeNo == 0x3f || + ModeNo == 0x42 || + ModeNo == 0x45 ) || + (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) { + colordepth >>= 1; + temp += colordepth; + } + + return(temp); +} + +USHORT +SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8}; + SHORT index; + USHORT modeflag; + + /* Do NOT check UseCustomMode, will skrew up FIFO */ + if(ModeNo == 0xfe) { + modeflag = SiS_Pr->CModeFlag; + } else { + if(ModeNo <= 0x13) + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + else + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + + index = (modeflag & ModeInfoFlag) - ModeEGA; + if(index < 0) index = 0; + return(ColorDepth[index]); +} + +void +SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempah=0,tempbl,infoflag,flag; + + flag = 0; + tempbl = 0xC0; + + if(SiS_Pr->UseCustomMode) { + infoflag = SiS_Pr->CInfoFlag; + } else { + infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */ + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + tempah = 0; + } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) { + tempah = SiS_Pr->SiS_LCDInfo; + } else tempah = infoflag >> 8; + + tempah &= 0xC0; + + tempah |= 0x20; + if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || + (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { + tempah |= 0xc0; + } + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + tempah >>= 3; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah); + } + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); + } + + } else { + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* ---- 300 series --- */ + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */ + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + tempah = SiS_Pr->SiS_LCDInfo; + if(SiS_Pr->SiS_LCDInfo & LCDSync) { + flag = 1; + } + } + if(flag != 1) tempah = infoflag >> 8; + tempah &= 0xC0; + + tempah |= 0x20; + if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; + +#if 0 + if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { + /* BIOS does something here @@@ */ + } +#endif + + tempah &= 0x3f; + tempah |= tempbl; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); + + } else { /* 630 - 301 */ + + tempah = infoflag >> 8; + tempah &= 0xC0; + tempah |= 0x20; + if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); + + } + +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* ------- 315 series ------ */ + + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - 30xLV */ + + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + tempah = infoflag >> 8; + if(SiS_Pr->SiS_LCDInfo & LCDSync) { + tempah = SiS_Pr->SiS_LCDInfo; + } + } else { + tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37); + } + tempah &= 0xC0; + + tempah |= 0x20; + if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); + + } else { /* 315 - 301, 301B */ + + tempah = infoflag >> 8; + if(!SiS_Pr->UseCustomMode) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDInfo & LCDSync) { + tempah = SiS_Pr->SiS_LCDInfo; + } + } + } + tempah &= 0xC0; + + tempah |= 0x20; + if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; + +#if 0 + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { + /* BIOS does something here @@@ */ + } +#endif + + if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* TEST, imitate BIOS bug */ + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + tempah |= 0xc0; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); + + } + +#endif /* SIS315H */ + } + } +} + +/* Set CRT2 FIFO on 300/630/730 */ +#ifdef SIS300 +void +SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp,index; + USHORT modeidindex,refreshratetableindex; + USHORT VCLK=0,MCLK,colorth=0,data2=0; + USHORT tempal, tempah, tempbx, tempcl, tempax; + USHORT CRT1ModeNo,CRT2ModeNo; + USHORT SelectRate_backup; + ULONG data,eax; + const UCHAR LatencyFactor[] = { + 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */ + 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */ + 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */ + 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */ + 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */ + 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */ + 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */ + 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */ + }; + const UCHAR LatencyFactor730[] = { + 69, 63, 61, + 86, 79, 77, + 103, 96, 94, + 120,113,111, + 137,130,128, /* <-- last entry, data below */ + 137,130,128, /* to avoid using illegal values */ + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + }; + const UCHAR ThLowB[] = { + 81, 4, 72, 6, 88, 8,120,12, + 55, 4, 54, 6, 66, 8, 90,12, + 42, 4, 45, 6, 55, 8, 75,12 + }; + const UCHAR ThTiming[] = { + 1, 2, 2, 3, 0, 1, 1, 2 + }; + + SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate; + + if(!SiS_Pr->CRT1UsesCustomMode) { + + CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */ + SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex); + SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); + SiS_Pr->SiS_SelectCRT2Rate = 0; + refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo, + modeidindex,HwDeviceExtension); + + if(CRT1ModeNo >= 0x13) { + index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK; + index &= 0x3F; + VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ + + colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,modeidindex); /* Get colordepth */ + colorth >>= 1; + if(!colorth) colorth++; + } + + } else { + + CRT1ModeNo = 0xfe; + VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */ + data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2; + switch(data2) { /* Get color depth */ + case 0 : colorth = 1; break; + case 1 : colorth = 1; break; + case 2 : colorth = 2; break; + case 3 : colorth = 2; break; + case 4 : colorth = 3; break; + case 5 : colorth = 4; break; + default: colorth = 2; + } + + } + + if(CRT1ModeNo >= 0x13) { + if(HwDeviceExtension->jChipType == SIS_300) { + index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A); + } else { + index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A); + } + index &= 0x07; + MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */ + + data2 = (colorth * VCLK) / MCLK; + + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + temp = ((temp & 0x00FF) >> 6) << 1; + if(temp == 0) temp = 1; + temp <<= 2; + temp &= 0xff; + + data2 = temp - data2; + + if((28 * 16) % data2) { + data2 = (28 * 16) / data2; + data2++; + } else { + data2 = (28 * 16) / data2; + } + + if(HwDeviceExtension->jChipType == SIS_300) { + + tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18); + tempah &= 0x62; + tempah >>= 1; + tempal = tempah; + tempah >>= 3; + tempal |= tempah; + tempal &= 0x07; + tempcl = ThTiming[tempal]; + tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + tempbx >>= 6; + tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + tempah >>= 4; + tempah &= 0x0c; + tempbx |= tempah; + tempbx <<= 1; + tempal = ThLowB[tempbx + 1]; + tempal *= tempcl; + tempal += ThLowB[tempbx]; + data = tempal; + + } else if(HwDeviceExtension->jChipType == SIS_730) { + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x80000050); + eax = SiS_GetReg3(0xcfc); +#else + eax = pciReadLong(0x00000000, 0x50); +#endif + tempal = (USHORT)(eax >> 8); + tempal &= 0x06; + tempal <<= 5; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x800000A0); + eax = SiS_GetReg3(0xcfc); +#else + eax = pciReadLong(0x00000000, 0xA0); +#endif + temp = (USHORT)(eax >> 28); + temp &= 0x0F; + tempal |= temp; + + tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */ + tempbx = 0; /* -- do it like the BIOS anyway... */ + tempax = tempbx; + tempbx &= 0xc0; + tempbx >>= 6; + tempax &= 0x0f; + tempax *= 3; + tempbx += tempax; + + data = LatencyFactor730[tempbx]; + data += 15; + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + if(!(temp & 0x80)) data += 5; + + } else { + + index = 0; + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + if(temp & 0x0080) index += 12; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x800000A0); + eax = SiS_GetReg3(0xcfc); +#else + /* We use pci functions X offers. We use tag 0, because + * we want to read/write to the host bridge (which is always + * 00:00.0 on 630, 730 and 540), not the VGA device. + */ + eax = pciReadLong(0x00000000, 0xA0); +#endif + temp = (USHORT)(eax >> 24); + if(!(temp&0x01)) index += 24; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x80000050); + eax = SiS_GetReg3(0xcfc); +#else + eax = pciReadLong(0x00000000, 0x50); +#endif + temp=(USHORT)(eax >> 24); + if(temp & 0x01) index += 6; + + temp = (temp & 0x0F) >> 1; + index += temp; + + data = LatencyFactor[index]; + data += 15; + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + if(!(temp & 0x80)) data += 5; + } + + data += data2; /* CRT1 Request Period */ + + SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; + SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; + + if(!SiS_Pr->UseCustomMode) { + + CRT2ModeNo = ModeNo; + SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex); + + refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo, + modeidindex,HwDeviceExtension); + + index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex, + refreshratetableindex,HwDeviceExtension); + VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ + + if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(ROMAddr[0x220] & 0x01) { + VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8); + } + } + } + + } else { + + CRT2ModeNo = 0xfe; + VCLK = SiS_Pr->CSRClock; /* Get VCLK */ + + } + + colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex); /* Get colordepth */ + colorth >>= 1; + if(!colorth) colorth++; + + data = data * VCLK * colorth; + if(data % (MCLK << 4)) { + data = data / (MCLK << 4); + data++; + } else { + data = data / (MCLK << 4); + } + + if(data <= 6) data = 6; + if(data > 0x14) data = 0x14; + + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x01); + if(HwDeviceExtension->jChipType == SIS_300) { + if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13; + else temp = (temp & (~0x1F)) | 0x16; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + temp = (temp & (~0x1F)) | 0x13; + } + } else { + if( ( (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) ) && + (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s or 730(s?) */ + { + temp = (temp & (~0x1F)) | 0x1b; + } else { + temp = (temp & (~0x1F)) | 0x16; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp); + + if( (HwDeviceExtension->jChipType == SIS_630) && + (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s, NOT 730 */ + { + if(data > 0x13) data = 0x13; + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data); + + } else { /* If mode <= 0x13, we just restore everything */ + + SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; + SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; + + } +} +#endif + +/* Set FIFO on 315/330 series */ +#ifdef SIS315H +void +SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ +#if 0 /* This code is obsolete */ + UCHAR CombCode[] = { 1, 1, 1, 4, 3, 1, 3, 4, + 4, 1, 4, 4, 5, 1, 5, 4}; + UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114, + 55, 87, 84,116,103,135,119,151}; + USHORT temp3,tempax,tempbx,tempcx; + USHORT tempcl, tempch; + USHORT index; + USHORT CRT1ModeNo,CRT2ModeNo; + USHORT ModeIdIndex; + USHORT RefreshRateTableIndex; + USHORT SelectRate_backup; + + SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate; +#endif + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B); + +#if 0 + if(!SiS_Pr->CRT1UsesCustomMode) { + + CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */ + SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&ModeIdIndex); + + SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); + SiS_Pr->SiS_SelectCRT2Rate = 0; + + /* Get REFIndex for crt1 refreshrate */ + RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo, + ModeIdIndex,HwDeviceExtension); + index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ + + tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */ + tempbx >>= 1; + if(!tempbx) tempbx++; + + } else { + + CRT1ModeNo = 0xfe; + tempax = SiS_Pr->CSRClock_CRT1; /* Get VCLK */ + tempbx = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2; + switch(tempbx) { /* Get color depth */ + case 0 : tempbx = 1; break; + case 1 : tempbx = 1; break; + case 2 : tempbx = 2; break; + case 3 : tempbx = 2; break; + case 4 : tempbx = 3; break; + case 5 : tempbx = 4; break; + default: tempbx = 2; + } + + } + + tempax *= tempbx; + + tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension); /* Get MCLK */ + + tempax /= tempbx; + + tempbx = tempax; + + tempax = 16; + + tempax -= tempbx; + + tempbx = tempax; /* tempbx = 16-DRamBus - DCLK*BytePerPixel/MCLK */ + + tempax = ((52 * 16) / tempbx); + + if ((52*16 % tempbx) != 0) { + tempax++; + } + tempcx = tempax; + tempcx += 40; + + /* get DRAM latency */ + tempcl = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 3) & 0x7; /* SR17[5:3] DRAM Queue depth */ + tempch = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 6) & 0x3; /* SR17[7:6] DRAM Grant length */ + + for (temp3 = 0; temp3 < 16; temp3 += 2) { + if ((CombCode[temp3] == tempcl) && (CombCode[temp3+1] == tempch)) { + temp3 = CRT2ThLow[temp3 >> 1]; + } + } + + tempcx += temp3; /* CRT1 Request Period */ + + SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; + SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; + + if(!SiS_Pr->UseCustomMode) { + + CRT2ModeNo = ModeNo; /* get CRT2 ModeNo */ + SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex); + + RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo, + ModeIdIndex,HwDeviceExtension); + + index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ + } else { + tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK; + } + + } else { + + CRT2ModeNo = 0xfe; /* Get VCLK */ + tempax = SiS_Pr->CSRClock; + + } + + tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex); /* Get colordepth */ + tempbx >>= 1; + if(!tempbx) tempbx++; + + tempax *= tempbx; + + tempax *= tempcx; + + tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension); /* Get MCLK */ + tempbx <<= 4; + + tempcx = tempax; + tempax /= tempbx; + if(tempcx % tempbx) tempax++; /* CRT1 Request period * TCLK * BytePerPixel / (MCLK*16) */ + + if (tempax > 0x37) tempax = 0x37; + + /* 650/LVDS, 650/301LV, 740, 330 overrule calculated value; 315 does not */ + if(HwDeviceExtension->jChipType >= SIS_650) { + tempax = 0x04; + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax); +#else + + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04); + +#endif +} + +USHORT +SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT index; + + index = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension); + if(index >= 4) { + index -= 4; + return(SiS_Pr->SiS_MCLKData_1[index].CLOCK); + } else { + return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); + } +} + +#endif + +/* Checked against 650/LVDS 1.10.07 BIOS */ +void +SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT modeflag; + USHORT PanelIndex,ResIndex; + const SiS_LVDSDesStruct *PanelDesPtr = NULL; + + if((SiS_Pr->UseCustomMode) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) || + (SiS_Pr->SiS_CustomT == CUT_PANEL848)) { + SiS_Pr->SiS_LCDHDES = 0; + SiS_Pr->SiS_LCDVDES = 0; + return; + } + + if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + +#ifdef SIS315H + SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &PanelIndex,&ResIndex); + + switch (PanelIndex) + { + case 0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1; break; /* --- expanding --- */ + case 1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1; break; + case 2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1; break; + case 3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1; break; + case 4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2; break; /* --- non expanding --- */ + case 5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2; break; + case 6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2; break; + case 7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2; break; + case 80: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_1; break; /* custom */ + case 81: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_2; break; + default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1; break; + } +#endif + + } else { + + SiS_GetLVDSDesPtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &PanelIndex,&ResIndex,HwDeviceExtension); + + switch (PanelIndex) + { + case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */ + case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break; + case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break; + case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break; + case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break; + case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break; + case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break; + case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break; + case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break; + case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break; + case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break; + case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break; + case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break; + case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break; + case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break; + case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break; + case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */ + case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break; + case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break; + case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break; + case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break; + case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break; + case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break; + case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break; + case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break; + case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break; + case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break; + case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break; + case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break; + case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break; + case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break; + case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break; + case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */ + case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break; + case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */ + case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break; + case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break; + case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break; + default: + if(HwDeviceExtension->jChipType < SIS_315H) + PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; + else + PanelDesPtr = SiS_Pr->SiS_PanelType01_1; + break; + } + } + SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES; + SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES; + + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD){ + if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + if(!(modeflag & HalfDCLK)) { + SiS_Pr->SiS_LCDHDES = 632; + } + } + } else { + if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) { + if( (HwDeviceExtension->jChipType < SIS_315H) || + (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) { + if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){ + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + if(HwDeviceExtension->jChipType < SIS_315H) { + if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320; + } else { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) + SiS_Pr->SiS_LCDHDES = 480; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) + SiS_Pr->SiS_LCDHDES = 804; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) + SiS_Pr->SiS_LCDHDES = 704; + if(!(modeflag & HalfDCLK)) { + SiS_Pr->SiS_LCDHDES = 320; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) + SiS_Pr->SiS_LCDHDES = 632; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) + SiS_Pr->SiS_LCDHDES = 542; + } + } + } + } + } + } + } + } + +} + +void +SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *PanelIndex, + USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempbx,tempal,modeflag; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } + + tempbx = 0; + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + tempbx = 50; + if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1; + /* Nothing special needed for SOverscan */ + /* PALM uses NTSC data, PALN uses PAL data */ + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + tempbx = SiS_Pr->SiS_LCDTypeInfo; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16; + if(SiS_Pr->SiS_LCDInfo & LCDPass11) { + tempbx = 32; + if(modeflag & HalfDCLK) tempbx++; + } + } + /* 630/LVDS and 650/LVDS (1.10.07) BIOS */ + if(SiS_Pr->SiS_SetFlag & SetDOSMode) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + tempal = 0x07; + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++; + } + } + } + + *PanelIndex = tempbx; + *ResIndex = tempal & 0x1F; +} + +#ifdef SIS315H +void +SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex) +{ + USHORT tempbx=0,tempal; + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 2; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 3; + else tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS; + + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 4; + + if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)) { + tempbx = 80; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } + } + } + + if(ModeNo <= 0x13) + tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + else + tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + + *PanelIndex = tempbx; + *ResIndex = tempal & 0x1F; +} +#endif + +void +SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr, USHORT ModeNo, USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT i,j,modeflag; + USHORT tempcl,tempah=0; +#ifdef SIS300 + USHORT temp; +#endif +#ifdef SIS315H + USHORT tempbl; +#endif + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + } + + /* BIOS does not do this (neither 301 nor LVDS) */ + /* (But it's harmless; see SetCRT2Offset) */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00); /* fix write part1 index 0 BTDRAM bit Bug */ + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + + /* 1. for LVDS/302B/302LV **LCDA** */ + + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */ + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7); + + } else { + + for(i=0,j=4; i<3; i++,j++) SiS_SetReg1(SiS_Pr->SiS_Part1Port,j,0); + + tempcl = SiS_Pr->SiS_ModeType; + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* ---- 300 series ---- */ + + /* For 301BDH: (with LCD via LVDS) */ + if(SiS_Pr->SiS_VBType & VB_NoLCD) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32); + temp &= 0xef; + temp |= 0x02; + if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { + temp |= 0x10; + temp &= 0xfd; + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp); + } + + if(ModeNo > 0x13) { + tempcl -= ModeVGA; + if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */ + tempah = ((0x10 >> tempcl) | 0x80); + } + } else tempah = 0x80; + + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0; + +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* ------- 315/330 series ------ */ + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08); + } + } + + if(ModeNo > 0x13) { + tempcl -= ModeVGA; + if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */ + tempah = (0x08 >> tempcl); + if (tempah == 0) tempah = 1; + tempah |= 0x40; + } + } else tempah = 0x40; + + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50; + +#endif /* SIS315H */ + + } + + if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) tempah = 0; + + if(HwDeviceExtension->jChipType < SIS_315H) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah); /* FUNCTION CONTROL */ + } else { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); /* FUNCTION CONTROL */ + } else { + if(IS_SIS740) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah); /* FUNCTION CONTROL */ + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); /* FUNCTION CONTROL */ + } + } + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + /* 2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */ + + tempah = 0x01; + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + tempah |= 0x02; + } + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { + tempah ^= 0x05; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { + tempah ^= 0x01; + } + } + + if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) tempah = 0; + + if(HwDeviceExtension->jChipType < SIS_315H) { + + /* ---- 300 series ---- */ + + tempah = (tempah << 5) & 0xFF; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah); + tempah = (tempah >> 5) & 0xFF; + + } else { + + /* ---- 315 series ---- */ + + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah); + + } + + if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { + tempah |= 0x10; + } + + if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) { + if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) { + tempah |= 0x80; + } + } else { + tempah |= 0x80; + } + + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(!(SiS_Pr->SiS_HiVision & 0x03)) { + tempah |= 0x20; + } + } + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah); + + tempah = 0; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(!(SiS_Pr->SiS_HiVision & 0x03)) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + SiS_Pr->SiS_SetFlag |= RPLLDIV2XO; + tempah |= 0x40; + } else { + if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) { + SiS_Pr->SiS_SetFlag |= RPLLDIV2XO; + tempah |= 0x40; + } + } + } + } else { + SiS_Pr->SiS_SetFlag |= RPLLDIV2XO; + tempah |= 0x40; + } + } + } + + /* For 302LV dual-channel */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) + tempah |= 0x40; + } + } + + if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) || + ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) && + (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) { + tempah |= 0x80; + } + + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah); + + } else { + + /* 3. for LVDS */ + + if(HwDeviceExtension->jChipType >= SIS_315H) { + + /* Inserted this entire section (BIOS 650/LVDS); added ModeType check + * (LVDS can only be slave in 8bpp modes) + */ + tempah = 0x80; + if( (modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { + if (SiS_Pr->SiS_VBInfo & DriverMode) { + tempah |= 0x02; + } + } + + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + tempah |= 0x02; + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + tempah ^= 0x01; + } + + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { + tempah = 1; + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah); + + } else { + + /* (added ModeType check) */ + tempah = 0; + if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { + tempah |= 0x02; + } + tempah <<= 5; + + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah); + + } + + } + + } + + /* Inserted the entire following section */ + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(HwDeviceExtension->jChipType >= SIS_315H) { + +#ifdef SIS315H + + unsigned char bridgerev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);; + + /* The following is nearly unpreditable and varies from machine + * to machine. Especially the 301DH seems to be a real trouble + * maker. Some BIOSes simply set the registers (like in the + * NoLCD-if-statements here), some set them according to the + * LCDA stuff. It is very likely that some machines are not + * treated correctly in the following, very case-orientated + * code. What do I do then...? + */ + + /* 740 variants match for 30xB, 301B-DH, 30xLV */ + + if(!(IS_SIS740)) { + tempah = 0x04; /* For all bridges */ + tempbl = 0xfb; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + tempah = 0x00; + if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) { + tempbl = 0xff; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); + } + + /* The following two are responsible for eventually wrong colors + * in TV output. The DH (VB_NoLCD) conditions are unknown; the + * b0 was found in some 651 machine (Pim); the b1 version in a + * 650 box (Jake). What is the criteria? + */ + + if(IS_SIS740) { + tempah = 0x30; + tempbl = 0xcf; + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { + tempah = 0x00; + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); + } else if(SiS_Pr->SiS_VBType & VB_SIS301) { + /* Fixes "TV-blue-bug" on 315+301 */ + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF); /* For 301 */ + } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30); /* For 30xLV */ + } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */ + } else { + tempah = 0x30; /* For 30xB (and 301BDH rev b1) */ + tempbl = 0xcf; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + tempah = 0x00; + if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) { + tempbl = 0xff; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); + } + + if(IS_SIS740) { + tempah = 0xc0; + tempbl = 0x3f; + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { + tempah = 0x00; + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah); + } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0); /* For 30xLV */ + } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0); /* For 30xB-DH rev b0 (or "DH on 651"? */ + } else { + tempah = 0xc0; /* For 301, 301B (and 301BDH rev b1) */ + tempbl = 0x3f; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + tempah = 0x00; + if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) { + tempbl = 0xff; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah); + } + + if(IS_SIS740) { + tempah = 0x80; + tempbl = 0x7f; + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { + tempah = 0x00; + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); + } else { + tempah = 0x00; /* For all bridges */ + tempbl = 0x7f; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + tempbl = 0xff; + if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) { + tempah |= 0x80; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); + } + +#endif /* SIS315H */ + + } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); + + if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || + ( (SiS_Pr->SiS_VBType & VB_NoLCD) && + (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) { + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F); + } else { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80); + } + + } + + } else { /* LVDS */ + +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + + tempah = 0x04; + tempbl = 0xfb; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + tempah = 0x00; + if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) { + tempbl = 0xff; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); + + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00); + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30); + + } else if(HwDeviceExtension->jChipType == SIS_550) { + +#if 0 + tempah = 0x00; + tempbl = 0xfb; + if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { + tempah = 0x00; + tempbl = 0xfb; + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); +#endif + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); + + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30); + } + + } +#endif + + } + +} + +void +SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + + SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + } else { + + if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) { + + /* Need LVDS Data for LCD on 301B-DH */ + SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + + } else { + + SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + } + + } + + } else { + + SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + } + + } else { + + SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + } +} + +/* Checked with 650/LVDS 1.10.07 BIOS */ +void +SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT CRT2Index, ResIndex; + const SiS_LVDSDataStruct *LVDSData = NULL; + + SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + SiS_Pr->SiS_RVBHCMAX = 1; + SiS_Pr->SiS_RVBHCFACT = 1; + SiS_Pr->SiS_NewFlickerMode = 0; + SiS_Pr->SiS_RVBHRS = 50; + SiS_Pr->SiS_RY1COE = 0; + SiS_Pr->SiS_RY2COE = 0; + SiS_Pr->SiS_RY3COE = 0; + SiS_Pr->SiS_RY4COE = 0; + } + + if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + +#ifdef SIS315H + SiS_GetCRT2PtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &CRT2Index,&ResIndex); + + switch (CRT2Index) { + case 0: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; + case 1: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break; + case 2: LVDSData = SiS_Pr->SiS_LVDS1280x960Data_1; break; + case 3: LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1; break; + case 4: LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1; break; + case 5: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break; + case 6: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break; + case 7: LVDSData = SiS_Pr->SiS_LVDS1280x960Data_2; break; + case 8: LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2; break; + case 9: LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2; break; + default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; + } +#endif + + } else { + + /* 301BDH needs LVDS Data */ + if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) { + SiS_Pr->SiS_IF_DEF_LVDS = 1; + } + + SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &CRT2Index,&ResIndex,HwDeviceExtension); + + /* 301BDH needs LVDS Data */ + if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) { + SiS_Pr->SiS_IF_DEF_LVDS = 0; + } + + switch (CRT2Index) { + case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break; + case 1: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; + case 2: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break; + case 3: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break; + case 4: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break; + case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break; + case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break; + case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break; + case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break; + case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break; + case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break; + case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break; + case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break; + case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break; + case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break; + case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break; + case 16: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break; + case 17: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break; + case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break; + case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break; + case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break; + case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break; + case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break; + case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break; + case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break; + case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break; + case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break; + case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break; + case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break; + case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break; + case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break; + case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break; + case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break; + case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break; + case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */ + default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; + } + } + + SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT; + SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT; + SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT; + SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; + SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; + } + + } else { + + if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { + if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { + if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) { + SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; + SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; + + if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { + if(ResIndex < 0x08) { + SiS_Pr->SiS_HDE = 1280; + SiS_Pr->SiS_VDE = 1024; + } + } +#if 0 + if(SiS_Pr->SiS_IF_DEF_FSTN) { + SiS_Pr->SiS_HDE = 320; + SiS_Pr->SiS_VDE = 480; + } +#endif + } + } + } + } + } +} + +void +SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempax,tempbx,modeflag; + USHORT resinfo; + USHORT CRT2Index,ResIndex; + const SiS_LCDDataStruct *LCDPtr = NULL; + const SiS_TVDataStruct *TVPtr = NULL; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + resinfo = 0; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + } + + SiS_Pr->SiS_NewFlickerMode = 0; + SiS_Pr->SiS_RVBHRS = 50; + SiS_Pr->SiS_RY1COE = 0; + SiS_Pr->SiS_RY2COE = 0; + SiS_Pr->SiS_RY3COE = 0; + SiS_Pr->SiS_RY4COE = 0; + + SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){ + + if(SiS_Pr->UseCustomMode) { + + SiS_Pr->SiS_RVBHCMAX = 1; + SiS_Pr->SiS_RVBHCFACT = 1; + SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal; + SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal; + SiS_Pr->SiS_HT = SiS_Pr->CHTotal; + SiS_Pr->SiS_VT = SiS_Pr->CVTotal; + SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; + SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; + + } else { + + SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + } + + } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + + SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &CRT2Index,&ResIndex,HwDeviceExtension); + + switch (CRT2Index) { + case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break; +/* case 7: TVPtr = SiS_Pr->SiS_St1HiTVData; break; */ + case 12: TVPtr = SiS_Pr->SiS_St2HiTVData; break; + case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break; + case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break; + case 8: TVPtr = SiS_Pr->SiS_StPALData; break; + case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break; + default: TVPtr = SiS_Pr->SiS_StPALData; break; /* Just to avoid a crash */ + } + + SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX; + SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT; + SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT; + SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT; + SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE; + SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE; + SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS; + SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode; + if(modeflag & HalfDCLK) { + SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS; + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + + if(SiS_Pr->SiS_HiVision != 3) { + if(resinfo == SIS_RI_1024x768) SiS_Pr->SiS_NewFlickerMode = 0x40; + if(resinfo == SIS_RI_1280x1024) SiS_Pr->SiS_NewFlickerMode = 0x40; + if(resinfo == SIS_RI_1280x720) SiS_Pr->SiS_NewFlickerMode = 0x40; + } + + switch(SiS_Pr->SiS_HiVision) { + case 2: + case 1: + case 0: + SiS_Pr->SiS_HT = 0x6b4; + SiS_Pr->SiS_VT = 0x20d; + /* Don't care about TVSimuMode */ + break; + default: + if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_SetFlag |= TVSimuMode; + + SiS_Pr->SiS_HT = ExtHiTVHT; + SiS_Pr->SiS_VT = ExtHiTVVT; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + SiS_Pr->SiS_HT = StHiTVHT; + SiS_Pr->SiS_VT = StHiTVVT; + if(!(modeflag & Charx8Dot)){ + SiS_Pr->SiS_HT = StHiTextTVHT; + SiS_Pr->SiS_VT = StHiTextTVVT; + } + } + } + } + + } else { + + SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE; + SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE; + SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE; + SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE; + + if(modeflag & HalfDCLK) { + SiS_Pr->SiS_RY1COE = 0x00; + SiS_Pr->SiS_RY2COE = 0xf4; + SiS_Pr->SiS_RY3COE = 0x10; + SiS_Pr->SiS_RY4COE = 0x38; + } + + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + SiS_Pr->SiS_HT = NTSCHT; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT; + } + SiS_Pr->SiS_VT = NTSCVT; + } else { + SiS_Pr->SiS_HT = PALHT; + SiS_Pr->SiS_VT = PALVT; + } + + } + + } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + + if(SiS_Pr->UseCustomMode) { + + SiS_Pr->SiS_RVBHCMAX = 1; + SiS_Pr->SiS_RVBHCFACT = 1; + SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal; + SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal; + SiS_Pr->SiS_HT = SiS_Pr->CHTotal; + SiS_Pr->SiS_VT = SiS_Pr->CVTotal; + SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; + SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; + + } else { + + SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &CRT2Index,&ResIndex,HwDeviceExtension); + + switch(CRT2Index) { + case 0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* VESA Timing */ + case 1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; /* VESA Timing */ + case 5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data; break; /* Obviously unused */ + case 6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data; break; /* Obviously unused */ + case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; /* Non-VESA Timing */ + case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; /* Non-VESA Timing */ + case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768; break; /* Non-expanding */ + case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break; /* Non-expanding */ + case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; /* 1280x960 */ + case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; /* VESA Timing */ + case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050; break; /* Non-expanding (let panel scale) */ + case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; /* Non-VESA Timing (let panel scale) */ + case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; /* VESA Timing */ + case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200; break; /* Non-expanding */ + case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; /* Non-VESA Timing */ + case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data; break; /* VESA Timing */ + case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768; break; /* Non-expanding */ + case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data; break; /* Non-VESA Timing */ + case 29: LCDPtr = SiS_Pr->SiS_NoScaleData; break; /* Generic no-scale data */ +#ifdef SIS315H + case 50: LCDPtr = (SiS_LCDDataStruct *)SiS310_ExtCompaq1280x1024Data; break; + case 51: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break; + case 52: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; +#endif + default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* Just to avoid a crash */ + } + + SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; + SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; + SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; + SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT; + SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT; + SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, + "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex); +#endif + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + tempax = 1024; + if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { + if(HwDeviceExtension->jChipType < SIS_315H) { + if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; + else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; + else tempbx = 768; + } else { + tempbx = 768; + } + } else { + if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527; + else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620; + else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775; + else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775; + else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; + else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; + else tempbx = 768; + } + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + tempax = 1280; + if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768; + else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800; + else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864; + else tempbx = 1024; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) { + tempax = 1280; + if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700; + else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800; + else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960; + else tempbx = 960; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + tempax = 1600; + if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875; + else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000; + else tempbx = 1200; + } else { + tempax = SiS_Pr->PanelXRes; + tempbx = SiS_Pr->PanelYRes; + } + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + tempax = SiS_Pr->SiS_VGAHDE; + tempbx = SiS_Pr->SiS_VGAVDE; + } + SiS_Pr->SiS_HDE = tempax; + SiS_Pr->SiS_VDE = tempbx; + } + } +} + +USHORT +SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT resindex; + + if(ModeNo <= 0x13) + resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + else + resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + + return(resindex); +} + +void +SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT xres,yres,modeflag=0,resindex; + + if(SiS_Pr->UseCustomMode) { + SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay; + SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay; + return; + } + + resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex); + + if(ModeNo <= 0x13) { + xres = SiS_Pr->SiS_StResInfo[resindex].HTotal; + yres = SiS_Pr->SiS_StResInfo[resindex].VTotal; + } else { + xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal; + yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal; + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + + if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) { + + if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) { + if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) { + if(yres == 350) yres = 400; + } + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) { + if(ModeNo == 0x12) yres = 400; + } + } + + if(ModeNo > 0x13) { + if(modeflag & HalfDCLK) xres *= 2; + if(modeflag & DoubleScanMode) yres *= 2; + } + + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + if(xres == 720) xres = 640; + } else { + if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* 301BDH */ + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVisionTV)) { + if(xres == 720) xres = 640; + } + if(SiS_Pr->SiS_SetFlag & SetDOSMode) { + yres = 400; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480; + } else { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480; + } + } + } else { + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVisionTV)) { + if(xres == 720) xres = 640; + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + /* BIOS bug - does this regardless of scaling */ + if(yres == 400) yres = 405; + } + if(yres == 350) yres = 360; + if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { + if(yres == 360) yres = 375; + } + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { + if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + if(yres == 350) yres = 357; + if(yres == 400) yres = 420; + if(yres == 480) yres = 525; + } + } + } + } + } + } + } else { + if(xres == 720) xres = 640; + if(SiS_Pr->SiS_SetFlag & SetDOSMode) { + yres = 400; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480; + } else { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480; + } + if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) { + yres = 480; + } + } + } + SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; + SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres; +} + +void +SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempbx=0,tempal=0; + USHORT Flag,resinfo=0; + + if(ModeNo <= 0x13) { + tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */ + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) { + tempbx = 15; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + tempbx = 20; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 21; + else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + tempbx = 23; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 24; + else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25; +#if 0 + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) { + tempbx = 26; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 27; + else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28; +#endif + } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 13; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14; + else tempbx = 29; + } else { + tempbx = 29; + if(ModeNo >= 0x13) { + /* 1280x768 and 1280x960 have same CRT2CRTC, + * so we change it here if 1280x960 is chosen + */ + if(resinfo == SIS_RI_1280x960) tempal = 10; + } + } + } else { + tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768; + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { + tempbx += 5; + /* GetRevisionID(); */ + /* BIOS only adds 5 once */ + tempbx += 5; + } + } + +#ifdef SIS315H + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + tempbx = 50; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 51; + else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52; + } +#endif + + } else { /* TV */ + + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && + (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) { + if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode); + tempbx = 2; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12; + } + } else { + if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3; + else tempbx = 4; + if(SiS_Pr->SiS_SetFlag & TVSimuMode) tempbx += 5; + } + + } + + tempal &= 0x3F; + + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) { + if(ModeNo > 0x13) { + if(tempal == 6) tempal = 7; + if((resinfo == SIS_RI_720x480) || + (resinfo == SIS_RI_720x576) || + (resinfo == SIS_RI_768x576)) { + tempal = 6; + } + } + } + + *CRT2Index = tempbx; + *ResIndex = tempal; + + } else { /* LVDS, 301B-DH (if running on LCD) */ + + Flag = 1; + tempbx = 0; + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { + Flag = 0; + tempbx = 10; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1; + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + tempbx += 2; + if(SiS_Pr->SiS_ModeType > ModeVGA) { + if(SiS_Pr->SiS_CHSOverScan) tempbx = 99; + } + if(SiS_Pr->SiS_CHPALM) { + tempbx = 90; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1; + } else if(SiS_Pr->SiS_CHPALN) { + tempbx = 92; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1; + } + } + } + } + + if(Flag) { + + if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) { + tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3; + if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { + tempbx = 82; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) { + tempbx = 18; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { + tempbx = 6; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) { + tempbx = 30; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) { + tempbx = 30; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) { + tempbx = 15; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) { + tempbx = 16; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + tempbx = 8; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + tempbx = 21; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) { + tempbx = 80; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } + + if(SiS_Pr->SiS_LCDInfo & LCDPass11) { + tempbx = 7; + } + + if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { + tempbx = 84; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } + + } + +#if 0 + if(SiS_Pr->SiS_IF_DEF_FSTN){ + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){ + tempbx = 14; + tempal = 6; + } + } +#endif + + if(SiS_Pr->SiS_SetFlag & SetDOSMode) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7; + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++; + } + + } + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(ModeNo > 0x13) { + if((resinfo == SIS_RI_720x480) || + (resinfo == SIS_RI_720x576) || + (resinfo == SIS_RI_768x576)) + tempal = 6; + } + } + + *CRT2Index = tempbx; + *ResIndex = tempal & 0x1F; + } +} + +#ifdef SIS315H +void +SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *CRT2Index, + USHORT *ResIndex) +{ + USHORT tempbx,tempal; + + tempbx = SiS_Pr->SiS_LCDResInfo; + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 4; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 3; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) tempbx = 2; + else tempbx -= SiS_Pr->SiS_Panel1024x768; + + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 5; + + if(ModeNo <= 0x13) + tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + else + tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + + *CRT2Index = tempbx; + *ResIndex = tempal & 0x1F; +} +#endif + +void +SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *CRT2Index, + USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempbx,tempal; + + if(ModeNo <= 0x13) + tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + else + tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + + tempbx = SiS_Pr->SiS_LCDResInfo; + + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16; + else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32; + +#ifdef SIS315H + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + tempbx = 100; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 101; + else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 102; + } + } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)) { + tempbx = 103; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 104; + else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 105; + } + } + } +#endif + + *CRT2Index = tempbx; + *ResIndex = tempal & 0x3F; +} + +USHORT +SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00 }; + USHORT RefreshRateTableIndex,i,backup_i; + USHORT modeflag,index,temp,backupindex; + + /* Do NOT check for UseCustomMode here, will skrew up FIFO */ + if(ModeNo == 0xfe) return 0; + + if(ModeNo <= 0x13) + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + else + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(modeflag & HalfDCLK) return(0); + } + } + + if(ModeNo < 0x14) return(0xFFFF); + + /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4]. + * On LVDS machines, CRT2 index is always 0 and will be + * set to 0 by the following code; this causes the function + * to take the first non-interlaced mode in SiS_Ext2Struct + */ + + index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x33); + index >>= SiS_Pr->SiS_SelectCRT2Rate; + index &= 0x0F; + backupindex = index; + + if(index > 0) index--; + + if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0; + } else { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_VBType & VB_NoLCD) + index = 0; + else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) + index = backupindex = 0; + } + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + index = 0; + } + } + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) { + temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo]; + if(index > temp) index = temp; + } + } else { + index = 0; + } + } + } + + RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; + ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID; + + /* 650/LVDS 1.10.07, 650/30xLV 1.10.6s */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(!(SiS_Pr->SiS_VBInfo & DriverMode)) { + if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) || + (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) { + if(backupindex <= 1) RefreshRateTableIndex++; + } + } + } + + i = 0; + do { + if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break; + temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag; + temp &= ModeInfoFlag; + if(temp < SiS_Pr->SiS_ModeType) break; + i++; + index--; + } while(index != 0xFFFF); + + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag; + if(temp & InterlaceMode) { + i++; + } + } + } + + i--; + + if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) { + backup_i = i; + if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,&i,HwDeviceExtension))) { + /* This is for avoiding random data to be used; i is + * in an undefined state if no matching CRT2 mode is + * found. + */ + i = backup_i; + } + } + + return(RefreshRateTableIndex + i); +} + +/* Checked against all (incl 650/LVDS (1.10.07), 630/301) BIOSes */ +BOOLEAN +SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempax,tempbx,resinfo; + USHORT modeflag,infoflag; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = 0; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + + tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID; + + tempax = 0; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { + tempax |= SupportRAMDAC2; + if(HwDeviceExtension->jChipType >= SIS_315H) { + tempax |= SupportTV; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if(resinfo == SIS_RI_1600x1200) tempax |= SupportTV1024; + } + } + } + } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + tempax |= SupportLCD; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) { + if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + (*i) = 0; + return(1); + } else { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) { + if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + return(0); + } else { + if((resinfo >= SIS_RI_1280x1024) && (resinfo != SIS_RI_1280x768)) { + return(0); + } + } + } + } + } + } + } + } else { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) { + if( (resinfo != SIS_RI_1024x600) && + ((resinfo == SIS_RI_512x384) || (resinfo >= SIS_RI_1024x768))) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) { + if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) { + if((resinfo != SIS_RI_1280x960) && (resinfo > SIS_RI_1024x768)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + if(resinfo > SIS_RI_1280x1024) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if(resinfo > SIS_RI_1024x768) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) { + if((resinfo == SIS_RI_512x384) || (resinfo > SIS_RI_800x600)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { + if((resinfo == SIS_RI_512x384) || + (resinfo == SIS_RI_400x300) || + (resinfo > SIS_RI_640x480)) return(0); + } + } + } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + if(SiS_Pr->SiS_HiVision == 3) { + tempax |= SupportHiVisionTV2; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){ + if(resinfo == SIS_RI_512x384) return(0); + if(resinfo == SIS_RI_400x300) return(0); + if(resinfo == SIS_RI_800x600) { + if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0); + } + if(resinfo > SIS_RI_800x600) return(0); + } + } else { + tempax |= SupportHiVisionTV; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){ + if(resinfo == SIS_RI_512x384) return(0); + if((resinfo == SIS_RI_400x300) || (resinfo == SIS_RI_800x600)) { + if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0); + } + if(resinfo > SIS_RI_800x600) return(0); + } + } + } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) { + tempax |= SupportTV; + tempax |= SupportTV1024; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) { + if(resinfo != SIS_RI_1024x768) { + if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) || + ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384)) ) { + tempax &= ~(SupportTV1024); + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) || + ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) { + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0); + } + } + } else { + if( (resinfo != SIS_RI_400x300) || + (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if(resinfo == SIS_RI_400x300) return(0); + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0); + } + } + } else return(0); + } + } + } + } else { + tempax &= ~(SupportTV1024); + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) || + ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) { + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0); + } + } + } else { + if( (resinfo != SIS_RI_400x300) || + (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if(resinfo == SIS_RI_400x300) return(0); + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0); + } + } + } else return(0); + } + } + } else { /* slavemode */ + if(resinfo != SIS_RI_1024x768) { + if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) || + ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384) ) ) { + tempax &= ~(SupportTV1024); + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) || + ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) { + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0); + } + } + } else { + if( (resinfo != SIS_RI_400x300) || + (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if(resinfo == SIS_RI_400x300) return(0); + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0); + } + } + } else return(0); + } + } + } + } + } else { /* 301 */ + tempax &= ~(SupportTV1024); + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) || + ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) { + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0); + } + } + } else { + if( (resinfo != SIS_RI_400x300) || + (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + if(resinfo == SIS_RI_400x300) return(0); + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0); + } + } + } else return(0); + } + } + } + + } else { /* for LVDS */ + + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + tempax |= SupportCHTV; + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + tempax |= SupportLCD; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) { + if((resinfo != SIS_RI_1280x768) && (resinfo >= SIS_RI_1280x1024)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) { + if((resinfo != SIS_RI_1024x600) && (resinfo >= SIS_RI_1024x768)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) { + if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + if((resinfo != SIS_RI_1400x1050) && (resinfo > SIS_RI_1280x1024)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + if(resinfo > SIS_RI_1600x1200) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + if(resinfo > SIS_RI_1280x1024) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if(resinfo > SIS_RI_1024x768) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){ + if(resinfo > SIS_RI_800x600) return(0); + if(resinfo == SIS_RI_512x384) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) { + if((resinfo != SIS_RI_1360x1024) && (resinfo > SIS_RI_1280x1024)) return(0); + } else if(SiS_Pr->SiS_LCDResInfo == Panel_848x480) { + if((resinfo != SIS_RI_1360x768) && + (resinfo != SIS_RI_848x480) && + (resinfo > SIS_RI_1024x768)) return(0); + } + } + } + + /* Look backwards in table for matching CRT2 mode */ + for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) { + infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag; + if(infoflag & tempax) { + return(1); + } + if ((*i) == 0) break; + } + /* Look through the whole mode-section of the table from the beginning + * for a matching CRT2 mode if no mode was found yet. + */ + for((*i) = 0; ; (*i)++) { + infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag; + if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) { + return(0); + } + if(infoflag & tempax) { + return(1); + } + } + return(1); +} + +void +SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo) +{ + USHORT temp1,temp2; + + /* We store CRT1 ModeNo in CR34 */ + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo); + temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8; + temp2 = ~(SetInSlaveMode >> 8); + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1); +} + +void +SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, + int checkcrt2mode) +{ + USHORT tempax,tempbx,temp; + USHORT modeflag, resinfo=0; + UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + } + + SiS_Pr->SiS_SetFlag = 0; + + SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag; + + tempbx = 0; + if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); +#if 0 + /* SiS_HiVision is only used on 315/330+30xLV */ + if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) { + if(SiS_Pr->SiS_HiVision & 0x03) { /* New from 650/30xLV 1.10.6s */ + temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); /* 0x83 */ + temp |= SetCRT2ToHiVisionTV; /* 0x80 */ + } + if(SiS_Pr->SiS_HiVision & 0x04) { /* New from 650/30xLV 1.10.6s */ + temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); /* 0x83 */ + temp |= SetCRT2ToSVIDEO; /* 0x08 */ + } + } +#endif +#if 0 + if(SiS_Pr->SiS_IF_DEF_FSTN) { /* fstn must set CR30=0x21 */ + temp = (SetCRT2ToLCD | SetSimuScanMode); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp); + } +#endif + tempbx |= temp; + tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8; + tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV); + tempbx |= tempax; + tempbx &= ~(SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display);; + +#ifdef SIS315H + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV)) { + /* From 1.10.7w, not in 1.10.8r */ + if(ModeNo == 0x03) { + /* Mode 0x03 is never in driver mode */ + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf); + } + /* From 1.10.7w, not in 1.10.8r */ + if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) { + /* Reset LCDA setting */ + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); + } + if(IS_SIS650) { + if(SiS_Pr->SiS_UseLCDA) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) { + if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); /* 3 */ + } + } + } +#if 0 /* We can't detect it this way; there are machines which do not use LCDA despite + * the chip revision + */ + if((tempbx & SetCRT2ToLCD) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD)) { + if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x36) & 0x0f) == SiS_Pr->SiS_Panel1400x1050) { + if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); /* 3 */ + } + } + } else { + if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); /* 3 */ + } + } + } + } +#endif + } + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) { + tempbx |= SetCRT2ToLCDA; + } + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(temp & SetToLCDA) + tempbx |= SetCRT2ToLCDA; + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(temp & EnableLVDSHiVision) + tempbx |= SetCRT2ToHiVisionTV; + } + } + } + +#endif /* SIS315H */ + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + temp = SetCRT2ToLCDA | SetCRT2ToSCART | SetCRT2ToLCD | + SetCRT2ToRAMDAC | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO | /* = 0x807C; */ + SetCRT2ToHiVisionTV; /* = 0x80FC; */ + } else { + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) + temp = SetCRT2ToLCDA | SetCRT2ToSCART | + SetCRT2ToLCD | SetCRT2ToHiVisionTV | + SetCRT2ToAVIDEO | SetCRT2ToSVIDEO; /* = 0x80bc */ + else + temp = SetCRT2ToLCDA | SetCRT2ToLCD; + } else { + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) + temp = SetCRT2ToTV | SetCRT2ToLCD; + else + temp = SetCRT2ToLCD; + } + } + + if(!(tempbx & temp)) { + tempax = DisableCRT2Display; + tempbx = 0; + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(tempbx & SetCRT2ToLCDA) { + tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode); + } + if(tempbx & SetCRT2ToRAMDAC) { + tempbx &= (0xFF00|SetCRT2ToRAMDAC|SwitchToCRT2|SetSimuScanMode); + } + if((tempbx & SetCRT2ToLCD) /* && (!(SiS_Pr->SiS_VBType & VB_NoLCD)) */ ) { + /* We initialize the Panel Link of the type of bridge is DH */ + tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode); + } + if(tempbx & SetCRT2ToSCART) { + tempbx &= (0xFF00|SetCRT2ToSCART|SwitchToCRT2|SetSimuScanMode); + tempbx |= SetPALTV; + } + if(tempbx & SetCRT2ToHiVisionTV) { + tempbx &= (0xFF00|SetCRT2ToHiVisionTV|SwitchToCRT2|SetSimuScanMode); + tempbx |= SetPALTV; + } + } else { /* LVDS */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(tempbx & SetCRT2ToLCDA) + tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode); + } + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(tempbx & SetCRT2ToTV) + tempbx &= (0xFF00|SetCRT2ToTV|SwitchToCRT2|SetSimuScanMode); + } + if(tempbx & SetCRT2ToLCD) { + tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode); + } + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(tempbx & SetCRT2ToLCDA) + tempbx |= SetCRT2ToLCD; + } + } + + if(tempax & DisableCRT2Display) { + if(!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { + tempbx = SetSimuScanMode | DisableCRT2Display; + } + } + + if(!(tempbx & DriverMode)){ + tempbx |= SetSimuScanMode; + } + + /* LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */ + if(SiS_Pr->SiS_ModeType <= ModeVGA) { + if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || + ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) { + modeflag &= (~CRT2Mode); + } + } + + if(!(tempbx & SetSimuScanMode)) { + if(tempbx & SwitchToCRT2) { + if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { + if( (HwDeviceExtension->jChipType >= SIS_315H) && + (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) { + if(resinfo != SIS_RI_1600x1200) + tempbx |= SetSimuScanMode; + } else { + tempbx |= SetSimuScanMode; + } + } + } else { + if(!(SiS_BridgeIsEnable(SiS_Pr,BaseAddr,HwDeviceExtension))) { + if(!(tempbx & DriverMode)) { + if(SiS_BridgeInSlave(SiS_Pr)) { + tempbx |= SetSimuScanMode; + } + } + } + } + } + + if(!(tempbx & DisableCRT2Display)) { + if(tempbx & DriverMode) { + if(tempbx & SetSimuScanMode) { + if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { + if( (HwDeviceExtension->jChipType >= SIS_315H) && + (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) { + if(resinfo != SIS_RI_1600x1200) { /* 650/301 BIOS */ + tempbx |= SetInSlaveMode; + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(tempbx & SetCRT2ToTV) { + if(!(tempbx & SetNotSimuMode)) + SiS_Pr->SiS_SetFlag |= TVSimuMode; + } + } + } /* 650/301 BIOS */ + } else { + tempbx |= SetInSlaveMode; + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(tempbx & SetCRT2ToTV) { + if(!(tempbx & SetNotSimuMode)) + SiS_Pr->SiS_SetFlag |= TVSimuMode; + } + } + } + } + } + } else { + tempbx |= SetInSlaveMode; + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(tempbx & SetCRT2ToTV) { + if(!(tempbx & SetNotSimuMode)) + SiS_Pr->SiS_SetFlag |= TVSimuMode; + } + } + } + } + + if(SiS_Pr->SiS_CHOverScan) { + if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35); + if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1) ) + tempbx |= SetCHTVOverScan; + } + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79); + if( (temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1) ) + tempbx |= SetCHTVOverScan; + } + if(SiS_Pr->SiS_CHSOverScan) { + tempbx |= SetCHTVOverScan; + } + } + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { +#ifdef SIS300 + if((HwDeviceExtension->jChipType==SIS_630) || + (HwDeviceExtension->jChipType==SIS_730)) { + if(ROMAddr && SiS_Pr->SiS_UseROM) { + OutputSelect = ROMAddr[0xfe]; + } + if(!(OutputSelect & EnablePALMN)) + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0x3F); + if(tempbx & SetCRT2ToTV) { + if(tempbx & SetPALTV) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35); + if(temp & EnablePALM) tempbx &= (~SetPALTV); + } + } + } +#endif +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(ROMAddr && SiS_Pr->SiS_UseROM) { + OutputSelect = ROMAddr[0xf3]; + if(HwDeviceExtension->jChipType >= SIS_330) { + OutputSelect = ROMAddr[0x11b]; + } + } + if(!(OutputSelect & EnablePALMN)) + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0x3F); + if(tempbx & SetCRT2ToTV) { + if(tempbx & SetPALTV) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(temp & EnablePALM) tempbx &= (~SetPALTV); + } + } + } +#endif + } + + /* PALM/PALN on Chrontel 7019 */ + SiS_Pr->SiS_CHPALM = SiS_Pr->SiS_CHPALN = FALSE; + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + if(tempbx & SetCRT2ToTV) { + if(tempbx & SetPALTV) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(temp & EnablePALM) SiS_Pr->SiS_CHPALM = TRUE; + else if(temp & EnablePALN) SiS_Pr->SiS_CHPALN = TRUE; + } + } + } + + SiS_Pr->SiS_VBInfo = tempbx; + + if(HwDeviceExtension->jChipType == SIS_630) { + SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo); + } + +#ifdef TWDEBUG +#ifdef LINUX_KERNEL + printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n", + SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); +#endif +#ifdef LINUX_XF86 + xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", + SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); +#endif +#endif + +} + +/* Setup general purpose IO for Chrontel communication */ +void +SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo) +{ + unsigned long acpibase; + unsigned short temp; + + if(!(SiS_Pr->SiS_ChSW)) return; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x80000874); /* get ACPI base */ + acpibase = SiS_GetReg3(0xcfc); +#else + acpibase = pciReadLong(0x00000800, 0x74); +#endif + acpibase &= 0xFFFF; + temp = SiS_GetReg4((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */ + temp &= 0xFEFF; + SiS_SetReg5((USHORT)(acpibase + 0x3c), temp); + temp = SiS_GetReg4((USHORT)(acpibase + 0x3c)); + temp = SiS_GetReg4((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */ + temp &= 0xFEFF; + if(!(myvbinfo & SetCRT2ToTV)) { + temp |= 0x0100; + } + SiS_SetReg5((USHORT)(acpibase + 0x3a), temp); + temp = SiS_GetReg4((USHORT)(acpibase + 0x3a)); +} + +void +SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempax=0,tempbx=0; + USHORT temp1=0,modeflag=0,tempcx=0; + USHORT StandTableIndex,CRT1Index; +#ifdef SIS315H + USHORT ResIndex,DisplayType,temp=0; + const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL; +#endif + + SiS_Pr->SiS_RVBHCMAX = 1; + SiS_Pr->SiS_RVBHCFACT = 1; + + if(ModeNo <= 0x13) { + + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex); + tempax = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[0]; + tempbx = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[6]; + temp1 = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[7]; + + } else { + + if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) { + +#ifdef SIS315H + temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,&ResIndex,&DisplayType); + + if(temp == 0) return; + + switch(DisplayType) { + case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break; + case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break; + case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break; + case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break; + case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break; + case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break; + case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break; + case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break; + case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break; + case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break; + case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break; + case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break; + case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break; + case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break; + case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break; + case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break; + case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break; + case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break; + case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break; + case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break; + case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break; + case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break; + case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; + case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break; + case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break; + case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break; + case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break; + case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break; + case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break; + case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break; + case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break; + case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break; + case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break; + case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break; + case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break; + case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break; + default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break; + } + tempax = (LVDSCRT1Ptr+ResIndex)->CR[0]; + tempax |= (LVDSCRT1Ptr+ResIndex)->CR[14] << 8; + tempax &= 0x03FF; + tempbx = (LVDSCRT1Ptr+ResIndex)->CR[6]; + tempcx = (LVDSCRT1Ptr+ResIndex)->CR[13] << 8; + tempcx &= 0x0100; + tempcx <<= 2; + tempbx |= tempcx; + temp1 = (LVDSCRT1Ptr+ResIndex)->CR[7]; +#endif + + } else { + + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; +#if 0 /* Not any longer */ + if(HwDeviceExtension->jChipType < SIS_315H) CRT1Index &= 0x3F; +#endif + tempax = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0]; + tempax |= SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] << 8; + tempax &= 0x03FF; + tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6]; + tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13] << 8; + tempcx &= 0x0100; + tempcx <<= 2; + tempbx |= tempcx; + temp1 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7]; + + } + + } + + if(temp1 & 0x01) tempbx |= 0x0100; + if(temp1 & 0x20) tempbx |= 0x0200; + + tempax += 5; + + /* Charx8Dot is no more used (and assumed), so we set it */ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + modeflag |= Charx8Dot; + } + + if(modeflag & Charx8Dot) tempax *= 8; + else tempax *= 9; + + /* From 650/30xLV 1.10.6s */ + if(modeflag & HalfDCLK) tempax <<= 1; + + tempbx++; + + SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; + SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx; +} + +void +SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr) +{ + if(HwDeviceExtension->jChipType >= SIS_315H) + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01); + else + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); +} + +void +SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr) +{ + if(HwDeviceExtension->jChipType >= SIS_315H) + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE); + else + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE); +} + +void +SiS_EnableCRT2(SiS_Private *SiS_Pr) +{ + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); +} + +void +SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT tempah,pushax=0,modenum; +#endif + USHORT temp=0; + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */ + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* 300 series */ + + if(HwDeviceExtension->jChipType == SIS_300) { /* New for 300+301LV */ + + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + } + } + if(SiS_Is301B(SiS_Pr,BaseAddr)) { + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f); + SiS_ShortDelay(SiS_Pr,1); + } + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); + SiS_DisplayOff(SiS_Pr); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) || + (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04); + } + + } else { + + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + } + if(SiS_Is301B(SiS_Pr,BaseAddr)) { + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f); + SiS_ShortDelay(SiS_Pr,1); + } + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); + SiS_DisplayOff(SiS_Pr); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); + if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) || + (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04); + } + } + +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* 315 series */ + + if(IS_SIS550650740660) { /* 550, 650, 740, 660 */ + +#if 0 + if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return; /* From 1.10.7w */ +#endif + + modenum = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34); + + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* LV */ + + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); + + if( (modenum <= 0x13) || + (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) || + (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) { + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + } + } + + if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { + SiS_DDC2Delay(SiS_Pr,0xff00); + SiS_DDC2Delay(SiS_Pr,0x6000); + SiS_DDC2Delay(SiS_Pr,0x8000); + + SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00); + + pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06); + + if(IS_SIS740) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); + } + + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + + if(!(IS_SIS740)) { + if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0xef; + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + tempah = 0xf7; + } + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah); + } + } + } + + } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* B-DH */ + /* This is actually bullshit. The B-DH bridge has cetainly no + * Part4 Index 26, since it has no ability to drive LCD panels + * at all. But as the BIOS does it, we do it, too... + */ + if(HwDeviceExtension->jChipType == SIS_650) { + if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef); + } + if((!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) || + (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00); + } + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 3); + } + } + + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef); + } + + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) { + tempah = 0x3f; + if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) { + tempah = 0x7f; + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0xbf; + } + } + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah); + } + + if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) { + + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF); + SiS_DisplayOff(SiS_Pr); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + } else { + SiS_DisplayOff(SiS_Pr); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF); + if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13)) { + SiS_DisplayOff(SiS_Pr); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp); + } + } + + } else { + + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) { + if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf); + SiS_DisplayOff(SiS_Pr); + } + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp); + } else { + SiS_DisplayOff(SiS_Pr); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp); + } + + } + + if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280)) { + + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10); /* 1.10.8r, 8m */ + + tempah = 0x3f; + if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) { + tempah = 0x7f; + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0xbf; + } + } + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah); + + if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) { /* 1.10.8r, 8m */ + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); + } /* 1.10.8r, 8m */ + + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf); + } + + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) { + if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00); + } + } + } + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax); + + } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { + + if(HwDeviceExtension->jChipType == SIS_650) { + if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) { + if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) || + (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) { + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2); + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4); + } + } + } + + } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) { + + if(HwDeviceExtension->jChipType == SIS_650) { + if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0xef; + if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) { + if(modenum > 0x13) { + tempah = 0xf7; + } + } + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah); + } + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) { + if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) || + (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) { + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2); + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4); + } + } + } + } + + } + + } else { /* 315, 330 - all bridge types */ + + if(SiS_Is301B(SiS_Pr,BaseAddr)) { + tempah = 0x3f; + if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) { + tempah = 0x7f; + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0xbf; + } + } + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah); + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_DisplayOff(SiS_Pr); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + } + } + if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) || + (!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) ) { + + if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) || + (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ) { + + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); + SiS_DisplayOff(SiS_Pr); + + } + + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp); + + } + + } /* 315/330 */ + +#endif /* SIS315H */ + + } + + } else { /* ============ For 301 ================ */ + + if(HwDeviceExtension->jChipType < SIS_315H) { + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + } + } + + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */ + SiS_DisplayOff(SiS_Pr); + + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + } + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */ + + if(HwDeviceExtension->jChipType >= SIS_315H) { + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp); + } else { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */ + if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) || + (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04); + } + } + + } + + } else { /* ============ For LVDS =============*/ + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* 300 series */ + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { + SiS_SetCH700x(SiS_Pr,0x090E); + } + + if(HwDeviceExtension->jChipType == SIS_730) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + } + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + } + } else { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { + + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { + + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) { + SiS_DisplayOff(SiS_Pr); + } + + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + } + } + } + } + + SiS_DisplayOff(SiS_Pr); + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); + + if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) || + (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04); + } + +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* 315 series */ + + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + + if(HwDeviceExtension->jChipType == SIS_740) { + temp = SiS_GetCH701x(SiS_Pr,0x61); + if(temp < 1) { + SiS_SetCH701x(SiS_Pr,0xac76); + SiS_SetCH701x(SiS_Pr,0x0066); + } + + if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetCH701x(SiS_Pr,0x3e49); + } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_SetCH701x(SiS_Pr,0x3e49); + } + } + + if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_Chrontel701xBLOff(SiS_Pr); + SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension); + } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_Chrontel701xBLOff(SiS_Pr); + SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension); + } + + if(HwDeviceExtension->jChipType != SIS_740) { + if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetCH701x(SiS_Pr,0x0149); + } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_SetCH701x(SiS_Pr,0x0149); + } + } + + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + SiS_DisplayOff(SiS_Pr); + } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_DisplayOff(SiS_Pr); + } else if(!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_DisplayOff(SiS_Pr); + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + } else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); + } + + if(HwDeviceExtension->jChipType == SIS_740) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); + } + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + } else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); + if(HwDeviceExtension->jChipType == SIS_550) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf); + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef); + } + } + } else { + if(HwDeviceExtension->jChipType == SIS_740) { + if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); + } + } else { + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); + } + } + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) { + /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */ + } else { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); + } + } + + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); + + if(HwDeviceExtension->jChipType == SIS_550) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); + } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); + } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); + } else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); + } + +#if 0 /* BIOS code makes no sense */ + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) { + /* Nothing there! */ + } + } + } +#endif + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) { + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04); + } + } + } + +#endif /* SIS315H */ + + } /* 310 series */ + + } /* LVDS */ + +} + +void +SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ + USHORT temp=0,tempah; +#ifdef SIS315H + USHORT temp1,pushax=0; + BOOLEAN delaylong = FALSE; +#endif + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */ + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* 300 series */ + + if(HwDeviceExtension->jChipType == SIS_300) { + + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); + if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) { + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0); + } + } + } + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ + if(SiS_BridgeInSlave(SiS_Pr)) { + tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp); + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ + if(SiS_Is301B(SiS_Pr,BaseAddr)) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0); + SiS_DisplayOn(SiS_Pr); + } else { + SiS_VBLongWait(SiS_Pr); + SiS_DisplayOn(SiS_Pr); + SiS_VBLongWait(SiS_Pr); + } + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + } + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01); + } + } + } + } + + } else { + + if((SiS_Pr->SiS_VBType & VB_NoLCD) && + (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) { + /* This is only for LCD output on 301B-DH via LVDS */ + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB); + if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) { + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0); + } + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */ +/* DoSomeThingPCI_On(SiS_Pr) */ + SiS_DisplayOn(SiS_Pr); + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); + if(SiS_BridgeInSlave(SiS_Pr)) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); + } + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + } + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x00); + } + } + } else { + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ + if(SiS_BridgeInSlave(SiS_Pr)) { + tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp); + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ + if(SiS_Is301B(SiS_Pr,BaseAddr)) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0); + SiS_DisplayOn(SiS_Pr); + } else { + SiS_VBLongWait(SiS_Pr); + SiS_DisplayOn(SiS_Pr); + SiS_VBLongWait(SiS_Pr); + } + } + + } +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* 315 series */ + + if(IS_SIS550650740660) { /* 550, 650, 740, 660 */ + +#if 0 + if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return; /* From 1.10.7w */ +#endif + + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + + if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef); /* 1.10.7u */ + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); /* 1.10.7u */ + } + + if(!(IS_SIS740)) { + if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0x10; + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) { + if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) { + tempah = 0x08; + } else { + tempah = 0x18; + } + } + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x4c,tempah); + } else { + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + tempah = 0x08; + } + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah); + } + } + } + + if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { + SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00); + SiS_DisplayOff(SiS_Pr); + pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06); + if(IS_SIS740) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); + } + } + + if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) { + if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { + if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { + SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2); + } + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); + SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2); + } + } + + if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) { + SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10); + delaylong = TRUE; + } + } + + } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { + + if(HwDeviceExtension->jChipType == SIS_650) { + if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10); + } + if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0); + } + } + + } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { + + if(HwDeviceExtension->jChipType == SIS_650) { + if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0x10; + if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) { + tempah = 0x18; + if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) { + tempah = 0x08; + } + } + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah); + } + } + + } + + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; + if(SiS_BridgeInSlave(SiS_Pr)) { + tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(!(tempah & SetCRT2ToRAMDAC)) { + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04)) temp |= 0x20; + } else temp |= 0x20; + } + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp); + + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ + + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e); + if(!(temp & 0x80)) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); + } + } else { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + } + } + + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20); + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20); + + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) { + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e); + if(!(temp & 0x80)) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); + } + } + + tempah = 0xc0; + if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) { + tempah = 0x80; + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0x40; + } + } + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah); + + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || + ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) && + (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); + } + + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); /* All this from 1.10.7u */ + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c); + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); + + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x08); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x10); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x4d); + if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x02) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b); + } + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); + + } else { + + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x12); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0xd0); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b); + if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) == 0x02) { /* @@@@ really == ? */ + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x40); + if(((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) != 0x03)) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x33); /* 00 */ + } + } + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); + if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x03) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); + } + } + + if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2); + } + + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10); /* 1.10.8r */ + + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + + if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) { + SiS_DisplayOn(SiS_Pr); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3); + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01); + } + } + + } else { + + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); + + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) { + SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10); + if(delaylong) { + SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10); + } + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01); + } + } + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax); + SiS_DisplayOn(SiS_Pr); + SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff); + + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); + } + + } + + } if(SiS_Pr->SiS_VBType & VB_NoLCD) { + + if(HwDeviceExtension->jChipType == SIS_650) { + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); + } + } + } + + } + + } else { /* 315, 330 */ + + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; + if(SiS_BridgeInSlave(SiS_Pr)) { + tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp); + + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ + + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E); + if(!(temp & 0x80)) + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20); + + if(SiS_Is301B(SiS_Pr,BaseAddr)) { + + temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E); + if(!(temp & 0x80)) + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); + + tempah = 0xc0; + if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) { + tempah = 0x80; + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + tempah = 0x40; + } + } + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah); + + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); + + } else { + + SiS_VBLongWait(SiS_Pr); + SiS_DisplayOn(SiS_Pr); + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F); + SiS_VBLongWait(SiS_Pr); + + } + + } /* 315, 330 */ + +#endif /* SIS315H */ + + } + + } else { /* ============ For 301 ================ */ + + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB); + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0); + } + } + + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ + if(SiS_BridgeInSlave(SiS_Pr)) { + tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp); + + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ + + if(HwDeviceExtension->jChipType >= SIS_315H) { + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E); + if(!(temp & 0x80)) + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */ + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ + + SiS_VBLongWait(SiS_Pr); + SiS_DisplayOn(SiS_Pr); + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); + } + SiS_VBLongWait(SiS_Pr); + + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7); + } + } + + } + + } else { /* =================== For LVDS ================== */ + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 /* 300 series */ + + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + if(HwDeviceExtension->jChipType == SIS_730) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + } + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB); + if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0); + } + } + + SiS_EnableCRT2(SiS_Pr); + SiS_DisplayOn(SiS_Pr); + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); + if(SiS_BridgeInSlave(SiS_Pr)) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { + if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) { + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + SiS_SetCH700x(SiS_Pr,0x0B0E); + } + } + + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { + if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) { + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1); + } + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7); + } + } + } + +#endif /* SIS300 */ + + } else { + +#ifdef SIS315H /* 315 series */ + +#if 0 /* BIOS code makes no sense */ + if(SiS_IsVAMode()) { + if(SiS_IsLCDOrLCDA()) { + } + } +#endif + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB); + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0); + } + } + + SiS_EnableCRT2(SiS_Pr); + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); + + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + temp = SiS_GetCH701x(SiS_Pr,0x66); + temp &= 0x20; + SiS_Chrontel701xBLOff(SiS_Pr); + } + + if(HwDeviceExtension->jChipType != SIS_550) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); + } + + if(HwDeviceExtension->jChipType == SIS_740) { + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); + } + } + } + + temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E); + if(!(temp1 & 0x80)) + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + if(temp) { + SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension); + } + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); + if(HwDeviceExtension->jChipType == SIS_550) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40); + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10); + } + } + } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + if(HwDeviceExtension->jChipType != SIS_740) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); + } + } + + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + + if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_Chrontel701xOn(SiS_Pr,HwDeviceExtension, BaseAddr); + } + + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr); + } else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr); + } + + } + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension); + SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr); + } else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension); + SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr); + } + } + } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) { + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7); + } + } + } + +#endif /* SIS315H */ + + } /* 310 series */ + + } /* LVDS */ + +} + +void +SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; + + /* Switch on LCD backlight on SiS30xLV */ + if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) || + (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) { + if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); + SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension); + } + if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); + } + } +} + +void +SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; + + /* Switch off LCD backlight on SiS30xLV */ + if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) || + (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00); + } + + if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) { + if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00); + } + } + } +} + +BOOLEAN +SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp,temp1; + UCHAR *ROMAddr; + + if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) { + if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff; + temp >>= 4; + temp = 1 << temp; + temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b]; + if(temp1 & temp) return(1); + else return(0); + } else return(0); + } else { + return(0); + } +} + +BOOLEAN +SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp,temp1; + UCHAR *ROMAddr; + + if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) { + if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff; + temp >>= 4; + temp = 1 << temp; + temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d]; + if(temp1 & temp) return(1); + else return(0); + } else return(0); + } else { + return(0); + } +} + +void +SiS_SetPanelDelayLoop(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT DelayTime, USHORT DelayLoop) +{ + int i; + for(i=0; i<DelayLoop; i++) { + SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, DelayTime); + } +} + +void +SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT DelayTime) +{ + USHORT PanelID, DelayIndex, Delay; +#ifdef SIS300 + USHORT temp; +#endif + + if(HwDeviceExtension->jChipType < SIS_315H) { + +#ifdef SIS300 + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 300 series, LVDS */ + + PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36); + + DelayIndex = PanelID >> 4; + + if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { + Delay = 3; + } else { + if(DelayTime >= 2) DelayTime -= 2; + + if(!(DelayTime & 0x01)) { + Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; + } else { + Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; + } + if((ROMAddr) && (SiS_Pr->SiS_UseROM)) { + if(ROMAddr[0x220] & 0x40) { + if(!(DelayTime & 0x01)) { + Delay = (USHORT)ROMAddr[0x225]; + } else { + Delay = (USHORT)ROMAddr[0x226]; + } + } + } + } + SiS_ShortDelay(SiS_Pr,Delay); + + } else { /* 300 series, 301(B) */ + + PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36); + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18); + if(!(temp & 0x10)) PanelID = 0x12; + + DelayIndex = PanelID >> 4; + + if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { + Delay = 3; + } else { + if(DelayTime >= 2) DelayTime -= 2; + + if(!(DelayTime & 0x01)) { + Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; + } else { + Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; + } + if((ROMAddr) && (SiS_Pr->SiS_UseROM)) { + if(ROMAddr[0x220] & 0x40) { + if(!(DelayTime & 0x01)) { + Delay = (USHORT)ROMAddr[0x225]; + } else { + Delay = (USHORT)ROMAddr[0x226]; + } + } + } + } + SiS_ShortDelay(SiS_Pr,Delay); + + } + +#endif /* SIS300 */ + + } else { + + if(HwDeviceExtension->jChipType == SIS_330) return; + +#ifdef SIS315H + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 315 series, LVDS */ + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { + PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36); + DelayIndex = PanelID >> 4; + if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { + Delay = 3; + } else { + if(DelayTime >= 2) DelayTime -= 2; + + if(!(DelayTime & 0x01)) { + Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0]; + } else { + Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1]; + } + if((ROMAddr) && (SiS_Pr->SiS_UseROM)) { + if(ROMAddr[0x13c] & 0x40) { + if(!(DelayTime & 0x01)) { + Delay = (USHORT)ROMAddr[0x17e]; + } else { + Delay = (USHORT)ROMAddr[0x17f]; + } + } + } + } + SiS_ShortDelay(SiS_Pr,Delay); + } + + } else { /* 315 series, 301(B) */ + + PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36); + DelayIndex = PanelID >> 4; + if(!(DelayTime & 0x01)) { + Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; + } else { + Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; + } + SiS_DDC2Delay(SiS_Pr, Delay * 4); + + } + +#endif /* SIS315H */ + + } + +} + +void +SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay) +{ + while(delay--) { + SiS_GenericDelay(SiS_Pr,0x19df); + } +} + +void +SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay) +{ + while(delay--) { + SiS_GenericDelay(SiS_Pr,0x42); + } +} + +void +SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay) +{ + USHORT temp,flag; + + flag = SiS_GetReg3(0x61) & 0x10; + + while(delay) { + temp = SiS_GetReg3(0x61) & 0x10; + if(temp == flag) continue; + flag = temp; + delay--; + } +} + +BOOLEAN +SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr) +{ + USHORT flag; + + flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01); + if(flag >= 0x0B0) return(1); + else return(0); +} + +BOOLEAN +SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT flag; + + if(HwDeviceExtension->jChipType == SIS_730) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13); + if(flag & 0x20) return(1); + } + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(flag & 0x20) return(1); + else return(0); +} + +BOOLEAN +SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT flag; + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((HwDeviceExtension->jChipType != SIS_650) || (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(flag & EnableDualEdge) return(1); + else return(0); + } else return(0); + } else +#endif + return(0); +} + +BOOLEAN +SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT flag; + + if(HwDeviceExtension->jChipType >= SIS_315H) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if((flag & EnableDualEdge) && (flag & SetToLCDA)) return(1); + else return(0); + } else +#endif + return(0); + } + +BOOLEAN +SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT flag; + + if(HwDeviceExtension->jChipType >= SIS_315H) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79); + if(flag & 0x10) return(1); + else return(0); + } else +#endif + return(0); + } + +#if 0 +BOOLEAN +SiS_Is315E(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT flag; + + if(HwDeviceExtension->jChipType >= SIS_315H) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f); + if(flag & 0x10) return(1); + else return(0); + } else +#endif + return(0); +} +#endif + +BOOLEAN +SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT flag; + + if(HwDeviceExtension->jChipType == SIS_650) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f); + flag &= 0xF0; + /* Check for revision != A0 only */ + if((flag == 0xe0) || (flag == 0xc0) || + (flag == 0xb0) || (flag == 0x90)) return 0; + else return 1; + } else +#endif + return 1; +} + +BOOLEAN +SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT flag; + + if(HwDeviceExtension->jChipType >= SIS_315H) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(flag & EnableLVDSHiVision) return(1); /* = YPrPb = 0x08 */ + else return(0); + } else +#endif + return(0); +} + +BOOLEAN +SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ +#ifdef SIS315H + USHORT flag; + + if(HwDeviceExtension->jChipType >= SIS_315H) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(flag & EnableLVDSScart) return(1); /* = Scart = 0x04 */ + else return(0); + } else +#endif + return(0); +} + +BOOLEAN +SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ + USHORT flag; + +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(flag & SetCRT2ToTV) return(1); + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(flag & EnableLVDSHiVision) return(1); /* = YPrPb = 0x08 */ + if(flag & EnableLVDSScart) return(1); /* = Scart = 0x04- TW inserted */ + else return(0); + } else +#endif + { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(flag & SetCRT2ToTV) return(1); + } + return(0); +} + +BOOLEAN +SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ + USHORT flag; + +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(flag & SetCRT2ToLCD) return(1); + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + if(flag & SetToLCDA) return(1); + else return(0); + } else +#endif + { + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(flag & SetCRT2ToLCD) return(1); + } + return(0); + +} + +BOOLEAN +SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr) +{ + USHORT flag; + + flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + if(flag & 0x20) return(0); + else return(1); +} + +BOOLEAN +SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT flag; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + return(0); + } else { + flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00); + if((flag == 1) || (flag == 2)) return(0); + else return(1); + } +} + +BOOLEAN +SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT flag; + + if(!(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension))) { + flag = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00); + if(HwDeviceExtension->jChipType < SIS_315H) { + /* 300 series (630/301B 2.04.5a) */ + flag &= 0xa0; + if((flag == 0x80) || (flag == 0x20)) return 0; + else return 1; + } else { + /* 315 series (650/30xLV 1.10.6s) */ + flag &= 0x50; + if((flag == 0x40) || (flag == 0x10)) return 0; + else return 1; + } + } + return 1; +} + +BOOLEAN +SiS_BridgeInSlave(SiS_Private *SiS_Pr) +{ + USHORT flag1; + + flag1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31); + if(flag1 & (SetInSlaveMode >> 8)) return 1; + else return 0; +} + +void +SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ +#ifdef SIS315H + USHORT temp; +#endif + + /* Note: This variable is only used on 30xLV systems. + CR38 has a different meaning on LVDS/CH7019 systems. + */ + + SiS_Pr->SiS_HiVision = 0; + if(HwDeviceExtension->jChipType >= SIS_315H) { +#ifdef SIS315H + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + temp &= 0x38; + SiS_Pr->SiS_HiVision = (temp >> 3); + } + } +#endif /* SIS315H */ + } +} + +void +SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp,modeflag,resinfo=0; + const unsigned char SiS300SeriesLCDRes[] = + { 0, 1, 2, 3, 7, 4, 5, 8, + 0, 0, 10, 0, 0, 0, 0, 15 }; + + SiS_Pr->SiS_LCDResInfo = 0; + SiS_Pr->SiS_LCDTypeInfo = 0; + SiS_Pr->SiS_LCDInfo = 0; + + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + } + + if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return; + + if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return; + + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36); + +#if 0 + /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */ + if(SiS_Pr->SiS_IF_DEF_FSTN) { + temp = 0x20 | SiS_Pr->SiS_Panel320x480; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp); + } +#endif + + if(HwDeviceExtension->jChipType < SIS_315H) { + SiS_Pr->SiS_LCDTypeInfo = temp >> 4; + } else { + SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1; + } + temp &= 0x0f; + if(HwDeviceExtension->jChipType < SIS_315H) { + /* Translate 300 series LCDRes to 315 series for unified usage */ + temp = SiS300SeriesLCDRes[temp]; + } + SiS_Pr->SiS_LCDResInfo = temp; + +#if 0 + if(SiS_Pr->SiS_IF_DEF_FSTN){ + SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480; + } +#endif + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301) + SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301; + } else { + if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS) + SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS; + } + + if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) { + if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax) + SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768; + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { + SiS_Pr->SiS_LCDResInfo = Panel_Barco1366; + } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { + SiS_Pr->SiS_LCDResInfo = Panel_848x480; + } + } + + switch(SiS_Pr->SiS_LCDResInfo) { + case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600; break; + case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; break; + case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break; + case Panel_640x480_3: + case Panel_640x480_2: + case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; break; + case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600; break; + case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864; break; + case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960; break; + case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768; break; + case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break; + case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; break; + case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break; + case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480; break; + case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX; + SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY; + break; + case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break; + case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480; break; + default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; break; + } + + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37); +#if 0 + if(SiS_Pr->SiS_IF_DEF_FSTN){ + /* Fake LVDS bridge for FSTN */ + temp = 0x04; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp); + } +#endif + SiS_Pr->SiS_LCDInfo = temp; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { + SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg sync, RGB24 */ + } + } + + if(!(SiS_Pr->UsePanelScaler)) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; + else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) { + /* For non-standard LCD resolution, we let the panel scale */ + SiS_Pr->SiS_LCDInfo |= DontExpandLCD; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) { + /* Bridge does not scale to 1280x960 */ + SiS_Pr->SiS_LCDInfo |= DontExpandLCD; + } + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) { + /* TEMP - no idea about the timing and zoom factors */ + SiS_Pr->SiS_LCDInfo |= DontExpandLCD; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) { + /* Bridge does not scale to 1280x1024 */ + SiS_Pr->SiS_LCDInfo |= DontExpandLCD; + } + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + /* TEMP - no idea about the timing and zoom factors */ + SiS_Pr->SiS_LCDInfo |= DontExpandLCD; + } + if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; + } + } + } + } + + + if(HwDeviceExtension->jChipType >= SIS_315H) { +#ifdef SIS315H + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) { + SiS_Pr->SiS_LCDInfo &= 0xFFEF; + SiS_Pr->SiS_LCDInfo |= LCDPass11; + } +#endif + } else { +#ifdef SIS300 + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { + if(!(ROMAddr[0x235] & 0x02)) { + SiS_Pr->SiS_LCDInfo &= 0xEF; + } + } + } + } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) { + SiS_Pr->SiS_LCDInfo &= 0xEF; + } + } +#endif + } + + /* Trumpion: Assume non-expanding */ + if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) { + SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); + } + + if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) { + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) { + if(ModeNo > 0x13) { + if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) { + SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; + } + } + } + } + if(ModeNo == 0x12) { + if(SiS_Pr->SiS_LCDInfo & LCDPass11) { + SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; + } + } + } + + if(modeflag & HalfDCLK) { + if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { + if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwDeviceExtension->jChipType < SIS_315H)) && + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) { + if(ModeNo > 0x13) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) { + if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; + } + } + } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; + } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; + } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; + } + + } + + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) { + SiS_Pr->SiS_SetFlag |= LCDVESATiming; + } + } else { + SiS_Pr->SiS_SetFlag |= LCDVESATiming; + } + +#ifdef SIS315H + /* 650/30xLV 1.10.6s */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,~0x04); + if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) { + /* Enable 302B/302LV dual link mode. + * (302B is a theory - not in any BIOS) + */ + if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + /* (Sets this in SenseLCD; new paneltypes) */ + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04); + } + } + if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04); + } + } + } + } +#endif + +#ifdef LINUX_KERNEL +#ifdef TWDEBUG + printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n", + SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); +#endif +#endif +#ifdef LINUX_XF86 + xf86DrvMsgVerb(0, X_PROBED, 3, + "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n", + SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag); +#endif + +} + +void +SiS_LongWait(SiS_Private *SiS_Pr) +{ + USHORT i; + + i = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); + + if(!(i & 0xC0)) { + for(i=0; i<0xFFFF; i++) { + if(!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) + break; + } + for(i=0; i<0xFFFF; i++) { + if((SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) + break; + } + } +} + +void +SiS_VBLongWait(SiS_Private *SiS_Pr) +{ + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { + SiS_VBWait(SiS_Pr); + } else { + SiS_LongWait(SiS_Pr); + } +} + +void +SiS_VBWait(SiS_Private *SiS_Pr) +{ + USHORT tempal,temp,i,j; + + temp = 0; + for(i=0; i<3; i++) { + for(j=0; j<100; j++) { + tempal = SiS_GetReg2(SiS_Pr->SiS_P3da); + if(temp & 0x01) { + if((tempal & 0x08)) continue; + if(!(tempal & 0x08)) break; + } else { + if(!(tempal & 0x08)) continue; + if((tempal & 0x08)) break; + } + } + temp ^= 0x01; + } +} + +void +SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + if(HwDeviceExtension->jChipType < SIS_315H) { +#ifdef SIS300 + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return; + } + if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) { + SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension); + } else { + SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension); + } +#endif + } else { +#ifdef SIS315H + if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) { + SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension); + } else { + SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension); + } +#endif + } +} + +void +SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT watchdog; +#ifdef SIS300 + USHORT i; +#endif + + if(HwDeviceExtension->jChipType >= SIS_315H) { +#ifdef SIS315H + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return; + watchdog = 65535; + while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog); + watchdog = 65535; + while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); +#endif + } else { +#ifdef SIS300 +#if 0 /* Not done in A901 BIOS */ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return; + } +#endif + for(i=0; i<10; i++) { + watchdog = 65535; + while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog); + if(watchdog) break; + } + for(i=0; i<10; i++) { + watchdog = 65535; + while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); + if(watchdog) break; + } +#endif + } +} + +void +SiS_WaitRetraceDDC(SiS_Private *SiS_Pr) +{ + USHORT watchdog; + + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return; + watchdog = 65535; + while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog); + watchdog = 65535; + while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); +} + +void +SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT watchdog; +#ifdef SIS300 + USHORT i; +#endif + + if(HwDeviceExtension->jChipType >= SIS_315H) { +#ifdef SIS315H + watchdog = 65535; + while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02) && --watchdog); + watchdog = 65535; + while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02)) && --watchdog); +#endif + } else { +#ifdef SIS300 + for(i=0; i<10; i++) { + watchdog = 65535; + while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02) && --watchdog); + if(watchdog) break; + } + for(i=0; i<10; i++) { + watchdog = 65535; + while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02)) && --watchdog); + if(watchdog) break; + } +#endif + } +} + +/* =========== Set and Get register routines ========== */ + +void +SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR) +{ + USHORT temp; + + temp = SiS_GetReg1(Port,Index); + temp = (temp & (DataAND)) | DataOR; + SiS_SetReg1(Port,Index,temp); +} + +void +SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND) +{ + USHORT temp; + + temp = SiS_GetReg1(Port,Index); + temp &= DataAND; + SiS_SetReg1(Port,Index,temp); +} + +void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR) +{ + USHORT temp; + + temp = SiS_GetReg1(Port,Index); + temp |= DataOR; + SiS_SetReg1(Port,Index,temp); +} + +/* ========================================================= */ + +static void +SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo) +{ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58); /* 48 */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda); /* de */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13); + if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38)) & 0x40) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x14); + } else { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x15); + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1b); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72); + } + } else { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x21); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x5a); + } + } + } +} + +/* Set 301 TV Encoder (and some LCD relevant) registers */ +void +SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo, + USHORT ModeIdIndex,USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT i, j, tempax, tempbx, tempcx, temp, temp1; + USHORT push1, push2; + const UCHAR *PhasePoint; + const UCHAR *TimingPoint; +#ifdef SIS315H + const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL; + USHORT resindex, CRT2Index; +#endif + USHORT modeflag, resinfo, crt2crtc; + ULONG longtemp, tempeax; +#ifdef SIS300 + const UCHAR atable[] = { + 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02, + 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02 + }; +#endif + +#ifdef SIS315H + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + /* 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */ + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03); + temp = 0x01; + if(ModeNo <= 0x13) temp = 0x03; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp); + } + } + SiS_SetTVSpecial(SiS_Pr, ModeNo); + return; + } +#endif + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + resinfo = 0; + crt2crtc = 0; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } + } + + tempcx = SiS_Pr->SiS_VBInfo; + tempax = (tempcx & 0x00FF) << 8; + tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8); + tempbx &= 0x0410; + temp = (tempax & 0x0800) >> 8; + temp >>= 1; + temp |= (((tempbx & 0xFF00) >> 8) << 1); + temp |= ((tempbx & 0x00FF) >> 3); + temp ^= 0x0C; + + /* From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */ + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + temp |= 0x0c; + } + + PhasePoint = SiS_Pr->SiS_PALPhase; + TimingPoint = SiS_Pr->SiS_PALTiming; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + + temp ^= 0x01; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + TimingPoint = SiS_Pr->SiS_HiTVSt2Timing; + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing; + else TimingPoint = SiS_Pr->SiS_HiTVTextTiming; + } + } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming; + + if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe; + + } else { + + if(SiS_Pr->SiS_VBInfo & SetPALTV){ + + TimingPoint = SiS_Pr->SiS_PALTiming; + PhasePoint = SiS_Pr->SiS_PALPhase; + + if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && + ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) { + PhasePoint = SiS_Pr->SiS_PALPhase2; + } + + } else { + + temp |= 0x10; + TimingPoint = SiS_Pr->SiS_NTSCTiming; + PhasePoint = SiS_Pr->SiS_NTSCPhase; + + if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && + ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) { + PhasePoint = SiS_Pr->SiS_NTSCPhase2; + } + + } + + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp); + + temp = 0; + if((HwDeviceExtension->jChipType == SIS_630)|| + (HwDeviceExtension->jChipType == SIS_730)) { + temp = 0x35; + } + if(HwDeviceExtension->jChipType >= SIS_315H) { + temp = 0x38; + } + if(temp) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) { + temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp); + if(temp1 & EnablePALM) { /* 0x40 */ + PhasePoint = SiS_Pr->SiS_PALMPhase; + if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && + ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) { + PhasePoint = SiS_Pr->SiS_PALMPhase2; + } + } + if(temp1 & EnablePALN) { /* 0x80 */ + PhasePoint = SiS_Pr->SiS_PALNPhase; + if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && + ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || + (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) { + PhasePoint = SiS_Pr->SiS_PALNPhase2; + } + } + } + } + } + +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) { + PhasePoint = SiS_Pr->SiS_SpecialPhase; + } + } + } + } + } +#endif + + for(i=0x31, j=0; i<=0x34; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]); + } + + for(i=0x01, j=0; i<=0x2D; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); + } + for(i=0x39; i<=0x45; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(!(SiS_Pr->SiS_ModeType & 0x07)) + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F); + } else { + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F); + } + } + + SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode); + + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE); + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + if(SiS_Pr->SiS_HiVision == 3) tempax = 950; + else tempax = 440; + } else { + if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520; + else tempax = 440; + } + + if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) || + ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_HiVision != 3) && + ( (SiS_Pr->SiS_VGAHDE == 1024) || ((SiS_Pr->SiS_VGAHDE != 1024) && (SiS_Pr->SiS_VDE <= tempax)) ) ) ) { + + tempax -= SiS_Pr->SiS_VDE; + tempax >>= 2; + tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8); + + temp = (tempax & 0xFF00) >> 8; + temp += (USHORT)TimingPoint[0]; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp); + + temp = (tempax & 0xFF00) >> 8; + temp += (USHORT)TimingPoint[1]; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp); + + if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && + (SiS_Pr->SiS_HiVision != 3) && + (SiS_Pr->SiS_VGAHDE >= 1024) ) { + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52); + } else { + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d); + } else { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11); + } + } + } + + } + + tempcx = SiS_Pr->SiS_HT; + + /* 650/30xLV 1.10.6s */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) { + tempcx >>= 1; + } + } + + tempcx--; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + tempcx--; + } + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1B,temp); + temp = (tempcx & 0xFF00) >> 8; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp); + + tempcx++; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + tempcx++; + } + tempcx >>= 1; + + push1 = tempcx; + + tempcx += 7; + if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (SiS_Pr->SiS_HiVision == 3)) { + tempcx -= 4; + } + temp = (tempcx & 0x00FF) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp); + + tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8); + tempbx += tempcx; + + push2 = tempbx; + + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,temp); + temp = ((tempbx & 0xFF00) >> 8) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp); + + tempbx = push2; + + tempbx += 8; + if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (SiS_Pr->SiS_HiVision == 3)) { + tempbx -= 4; + tempcx = tempbx; + } + temp = (tempbx & 0x00FF) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp); + + j += 2; + tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8))); + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,temp); + temp = ((tempcx & 0xFF00) >> 8) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp); + + tempcx += 8; + if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (SiS_Pr->SiS_HiVision == 3)) { + tempcx -= 4; + } + temp = (tempcx & 0x00FF) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp); + + tempcx = push1; + + j += 2; + tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8)); + temp = (tempcx & 0x00FF) << 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,temp); + + tempcx -= 11; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { + tempax = SiS_GetVGAHT2(SiS_Pr) - 1; + tempcx = tempax; + } + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp); + + tempbx = SiS_Pr->SiS_VDE; + if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746; + if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746; + if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853; + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1; + } else { + if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) { + tempbx >>= 1; + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + if(ModeNo <= 0x13) { + if(crt2crtc == 1) { + tempbx++; + } + } + } else { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(crt2crtc == 4) /* BIOS calls GetRatePtrCRT2 here - does not make sense */ + if(SiS_Pr->SiS_ModeType <= 3) tempbx++; + } + } + } + } + tempbx -= 2; + temp = tempbx & 0x00FF; + if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (SiS_Pr->SiS_HiVision == 3)) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++; + } + } + /* From 1.10.7w - doesn't make sense */ + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { /* SetFlag?? */ + if(ModeNo == 0x03) temp++; + } + } + } + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2F,temp); + + tempax = (tempcx & 0xFF00) | (tempax & 0x00FF); + tempbx = ((tempbx & 0xFF00) << 6) | (tempbx & 0x00FF); + tempax |= (tempbx & 0xFF00); + if(HwDeviceExtension->jChipType < SIS_315H) { + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) { + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) { /* New from 630/301B (II) BIOS */ + tempax |= 0x1000; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) tempax |= 0x2000; + } + } + } else { + /* TODO Check this with other BIOSes */ + if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) + /* && (SiS_Pr->SiS_HiVision == 3) */ ) { + tempax |= 0x1000; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) tempax |= 0x2000; + } + } + temp = (tempax & 0xFF00) >> 8; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp); + + /* 650/30xLV 1.10.6s */ + if(HwDeviceExtension->jChipType > SIS_315H) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60); + } + } + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + if(SiS_Pr->SiS_HiVision != 3) { + for(i=0, j=0; i<=0x2d; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]); + } + for(i=0x39; i<=0x45; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]); + } + } + } + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + tempbx = SiS_Pr->SiS_VDE; + if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) { + tempbx >>= 1; + } + tempbx -= 3; + tempbx &= 0x03ff; + temp = ((tempbx & 0xFF00) >> 8) << 5; + temp |= 0x18; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp); + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp); + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + tempax = 0; + if(SiS_Pr->SiS_HiVision & 0x03) { + tempax = 0x3000; + if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000; + } + temp = (tempax & 0xFF00) >> 8; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp); + } + } + } + + tempbx &= 0x00FF; + if(!(modeflag & HalfDCLK)) { + if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) { + tempbx |= 0x2000; + tempax &= 0x00FF; + } + } + + tempcx = 0x0101; +/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) { */ /* BIOS BUG? */ + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) { + if(!(SiS_Pr->SiS_HiVision & 0x03)) { + if(SiS_Pr->SiS_VGAHDE >= 1024) { + if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) { + tempcx = 0x1920; + if(SiS_Pr->SiS_VGAHDE >= 1280) { + tempcx = 0x1420; + tempbx &= 0xDFFF; + } + } + } + } + } + + if(!(tempbx & 0x2000)) { + if(modeflag & HalfDCLK) { + tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF); + } + longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF); + longtemp <<= 13; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + longtemp <<= 3; + } + tempeax = longtemp / SiS_Pr->SiS_HDE; + if(longtemp % SiS_Pr->SiS_HDE) tempeax++; + tempax = (USHORT)tempeax; + tempcx = (tempcx & 0xFF00) | ((tempax & 0xFF00) >> (8 + 5)); + tempbx |= (tempax & 0x1F00); + tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF); + } + + temp = (tempax & 0xFF00) >> 8; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x44,temp); + temp = (tempbx & 0xFF00) >> 8; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp); + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + temp = tempcx & 0x00FF; + if(tempbx & 0x2000) temp = 0; + temp |= 0x18; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp); + + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + tempbx = 0x0382; + tempcx = 0x007e; + } else { + tempbx = 0x0369; + tempcx = 0x0061; + } + temp = (tempbx & 0x00FF) ; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp); + temp = (tempcx & 0x00FF) ; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp); + temp = (tempcx & 0x0300) >> (8 - 2); + temp |= ((tempbx >> 8) & 0x03); + if(HwDeviceExtension->jChipType < SIS_315H) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp); + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp); + } + + temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3)); + } + + temp = 0; + if((HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730)) { + temp = 0x35; + } else if(HwDeviceExtension->jChipType >= SIS_315H) { + temp = 0x38; + } + if(temp) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) { /* 0x40 */ + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF); + temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1); + } + } + } + } + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00); + } + } + } + +#if 0 /* Old: Why HiVision? */ + if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) { + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00); + } + } +#endif + + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex, + RefreshRateTableIndex, BaseAddr, ModeNo); + return; + } + } else { + /* !!! The following is a duplicate, done for LCDA as well (see above) */ + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + SiS_SetTVSpecial(SiS_Pr, ModeNo); + return; + } + } + + /* From here: Part2 LCD setup */ + + tempbx = SiS_Pr->SiS_HDE; + if(HwDeviceExtension->jChipType >= SIS_315H) { + /* 650/30xLV 1.10.6s */ + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1; + } + tempbx--; /* RHACTE=HDE-1 */ + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp); + temp = (tempbx & 0xFF00) >> 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp); + + temp = 0x01; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + if(SiS_Pr->SiS_ModeType == ModeEGA) { + if(SiS_Pr->SiS_VGAHDE >= 1024) { + temp = 0x02; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { + temp = 0x01; + } + } + } + } + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp); + + tempbx = SiS_Pr->SiS_VDE; /* RTVACTEO = VDE - 1 */ + /* push1 = tempbx; */ + tempbx--; + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp); + temp = ((tempbx & 0xFF00) >> 8) & 0x07; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp); + + tempcx = SiS_Pr->SiS_VT; + /* push2 = tempcx; */ + tempcx--; + temp = tempcx & 0x00FF; /* RVTVT = VT - 1 */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp); + + temp = (tempcx & 0xFF00) >> 8; + temp <<= 5; + + /* Enable dithering; newer versions only do this for 32bpp mode */ + if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) { + if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10; + } else if(HwDeviceExtension->jChipType < SIS_315H) { + temp |= 0x10; + } else { + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + /* 650/30xLV 1.10.6s */ + if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { + if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { /* 32bpp mode? */ + temp |= 0x10; + } + } + } else { + temp |= 0x10; + } + } + + /* 630/301 does not do all this */ + if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { + if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { + if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) && + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) { +#ifdef SIS315H + if(SiS_Pr->SiS_LCDInfo & LCDSync) { + temp |= (SiS_Pr->SiS_LCDInfo >> 6); + } +#endif + } else { + /* 650/30xLV 1.10.6s */ + temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6); + temp |= 0x08; /* From 1.10.7w */ + if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; /* From 1.10.7w */ + } + } else { + if(SiS_Pr->SiS_LCDInfo & LCDSync) { + temp |= (SiS_Pr->SiS_LCDInfo >> 6); + } + } + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp); + + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0); + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0); + + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB); + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF); + + if((HwDeviceExtension->jChipType >= SIS_315H) && + (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && + ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) ) { + +#ifdef SIS315H /* ------------- 315/330 series ------------ */ + + /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) results + * in a black bar in modes < 1024; if the panel is non-expanding, the bridge + * scales all modes to 1024. All modes in both variants (exp/non-exp) work. + */ + + SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &CRT2Index,&resindex,HwDeviceExtension); + + switch(CRT2Index) { + case Panel_1024x768 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; /* "Normal" */ + case Panel_1280x1024 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break; + case Panel_1400x1050 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break; + case Panel_1600x1200 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break; + case Panel_1024x768 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2; break; /* Non-Expanding */ + case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break; + case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break; + case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break; + case Panel_1024x768 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break; /* VESA Timing */ + case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break; + case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break; + case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break; + case 100: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_1; break; /* Custom */ + case 101: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_2; break; + case 102: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_3; break; + case 103: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_1; break; /* Custom */ + case 104: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_2; break; + case 105: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_3; break; + default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break; + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); + for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); + } + for(j = 0x1c; j <= 0x1d; i++, j++ ) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); + } + for(j = 0x1f; j <= 0x21; i++, j++ ) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); + + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { + if(SiS_Pr->SiS_VGAVDE == 525) { + temp = 0xc3; + if(SiS_Pr->SiS_ModeType <= ModeVGA) { + temp++; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2; + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3); + } else if(SiS_Pr->SiS_VGAVDE == 420) { + temp = 0x4d; + if(SiS_Pr->SiS_ModeType <= ModeVGA) { + temp++; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++; + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp); + } + } + + /* !!! This is a duplicate, done for LCDA as well - see above */ + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03); /* Not done in 1.10.7w */ + temp = 1; + if(ModeNo <= 0x13) temp = 3; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp); + } + } +#endif + + } else { /* ------ 300 series and other bridges, other LCD resolutions ------ */ + + /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) makes + * the panel scale at modes < 1024 (no black bars); if the panel is non-expanding, + * the bridge scales all modes to 1024. + * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!! + */ + + /* cx = VT - 1 */ + + tempcx++; + + tempbx = SiS_Pr->PanelYRes; + + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + tempbx = SiS_Pr->SiS_VDE - 1; + tempcx--; + } + + tempax = 1; + if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { + if(tempbx != SiS_Pr->SiS_VDE) { + tempax = tempbx; + if(tempax < SiS_Pr->SiS_VDE) { + tempax = 0; + tempcx = 0; + } else { + tempax -= SiS_Pr->SiS_VDE; + } + tempax >>= 1; + } + tempcx -= tempax; /* lcdvdes */ + tempbx -= tempax; /* lcdvdee */ + } +#if 0 /* meaningless: 1 / 2 = 0... */ + else { + tempax >>= 1; + tempcx -= tempax; /* lcdvdes */ + tempbx -= tempax; /* lcdvdee */ + } +#endif + + /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx); +#endif + + temp = tempcx & 0x00FF; /* RVEQ1EQ=lcdvdes */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp); + temp = tempbx & 0x00FF; /* RVEQ2EQ=lcdvdee */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,temp); + + temp = ((tempbx & 0xFF00) >> 8) << 3; + temp |= ((tempcx & 0xFF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp); + + tempbx = SiS_Pr->SiS_VT; /* push2; */ + tempax = SiS_Pr->SiS_VDE; /* push1; */ + tempcx = (tempbx - tempax) >> 4; + tempbx += tempax; + tempbx >>= 1; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx -= 10; + + /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */ + + if(SiS_Pr->UseCustomMode) { + tempbx = SiS_Pr->CVSyncStart; + } + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx); +#endif + + temp = tempbx & 0x00FF; /* RTVACTEE = lcdvrs */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp); + + temp = ((tempbx & 0xFF00) >> 8) << 4; + tempbx += (tempcx + 1); + temp |= (tempbx & 0x000F); + + if(SiS_Pr->UseCustomMode) { + temp &= 0xf0; + temp |= (SiS_Pr->CVSyncEnd & 0x0f); + } + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f)); +#endif + + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp); + + /* Code from 630/301B (I+II) BIOS */ + + if(!SiS_Pr->UseCustomMode) { + if( ( ( (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) ) && + (HwDeviceExtension->jChipRevision > 2) ) && + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) && + (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) && + (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) { + if(ModeNo == 0x13) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6); + } else { + if((crt2crtc & 0x3F) == 4) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2); + } + } + } + } + +#ifdef SIS300 + if(HwDeviceExtension->jChipType < SIS_315H) { + if(!SiS_Pr->UseCustomMode) { + if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) { + crt2crtc &= 0x1f; + tempcx = 0; + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + tempcx += 7; + } + } + tempcx += crt2crtc; + if(crt2crtc >= 4) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff); + } + + if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(crt2crtc == 4) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28); + } + } + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]); + } + } + } +#endif + + tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2; /* (HT - HDE) >> 2 */ + tempbx = SiS_Pr->SiS_HDE + 7; /* lcdhdee */ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + tempbx += 2; + } + push1 = tempbx; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx); +#endif + + temp = tempbx & 0x00FF; /* RHEQPLE = lcdhdee */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp); + temp = (tempbx & 0xFF00) >> 8; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp); + + temp = 7; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + temp += 2; + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp); /* RHBLKE = lcdhdes[7:0] */ + SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F); /* lcdhdes [11:8] */ + + tempbx += tempcx; + push2 = tempbx; + + if(SiS_Pr->UseCustomMode) { + tempbx = SiS_Pr->CHSyncStart + 7; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + tempbx += 2; + } + } + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx); +#endif + + temp = tempbx & 0x00FF; /* RHBURSTS = lcdhrs */ + if(!SiS_Pr->UseCustomMode) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { + if(SiS_Pr->SiS_HDE == 1280) temp = 0x47; + } + } + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp); + temp = (tempbx & 0x0F00) >> 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp); + + tempbx = push2; + tempcx <<= 1; + tempbx += tempcx; + + if(SiS_Pr->UseCustomMode) { + tempbx = SiS_Pr->CHSyncEnd + 7; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + tempbx += 2; + } + } + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx); +#endif + + temp = tempbx & 0x00FF; /* RHSYEXP2S = lcdhre */ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp); + + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { + if(SiS_Pr->SiS_VGAVDE == 525) { + if(SiS_Pr->SiS_ModeType <= ModeVGA) + temp=0xC6; + else + temp=0xC3; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3); + } else if(SiS_Pr->SiS_VGAVDE == 420) { + if(SiS_Pr->SiS_ModeType <= ModeVGA) + temp=0x4F; + else + temp=0x4D; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp); + } + } + SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex, + RefreshRateTableIndex, BaseAddr, ModeNo); + + } /* HwDeviceExtension */ +} + +USHORT +SiS_GetVGAHT2(SiS_Private *SiS_Pr) +{ + ULONG tempax,tempbx; + + tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF; + tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT; + tempax = (tempax * SiS_Pr->SiS_HT) / tempbx; + return((USHORT) tempax); +} + +/* New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */ +void +SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeIdIndex, USHORT RefreshRateTableIndex, + USHORT BaseAddr, USHORT ModeNo) +{ + USHORT crt2crtc, resindex; + int i,j; + const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL; + + if(HwDeviceExtension->jChipType != SIS_300) return; + if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return; + if(SiS_Pr->UseCustomMode) return; + + if(ModeNo <= 0x13) { + crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } + + resindex = crt2crtc & 0x3F; + if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; + else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2; + + /* The BIOS code (1.16.51) is obviously a fragment! */ + if(ModeNo > 0x13) { + CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; + resindex = 4; + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); + for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); + } + for(j = 0x1c; j <= 0x1d; i++, j++ ) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); + } + for(j = 0x1f; j <= 0x21; i++, j++ ) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); +} + +void +SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp; + USHORT i; + const UCHAR *tempdi; + USHORT modeflag; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; + + if(ModeNo<=0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + } + +#ifndef SIS_CP + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00); +#endif + +#ifdef SIS_CP + SIS_CP_INIT301_CP +#endif + + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA); + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8); + } else { + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5); + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7); + } else { + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6); + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf); + } + } + + temp = 0; + if((HwDeviceExtension->jChipType == SIS_630)|| + (HwDeviceExtension->jChipType == SIS_730)) { + temp = 0x35; + } else if(HwDeviceExtension->jChipType >= SIS_315H) { + temp = 0x38; + } + if(temp) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){ /* 0x40 */ + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA); + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8); + SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8); + } + } + } + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + tempdi = SiS_Pr->SiS_HiTVGroup3Data; + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + tempdi = SiS_Pr->SiS_HiTVGroup3Simu; + if(!(modeflag & Charx8Dot)) { + tempdi = SiS_Pr->SiS_HiTVGroup3Text; + } + } + if(SiS_Pr->SiS_HiVision & 0x03) { + tempdi = SiS_HiTVGroup3_1; + if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2; + } + for(i=0; i<=0x3E; i++){ + SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]); + } + } + +#ifdef SIS_CP + SIS_CP_INIT301_CP2 +#endif + +} + +/* Set 301 VGA2 registers */ +void +SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex,USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo; + ULONG tempebx,tempeax,templong; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + resinfo = 0; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + } + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e); + } + } + } + + if(SiS_Pr->SiS_VBType & VB_SIS302LV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f); + } + } + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + /* From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */ + /* This is a duplicate; done at the end, too */ + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c); + } + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); + } + return; + } + } + + temp = SiS_Pr->SiS_RVBHCFACT; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x13,temp); + + tempbx = SiS_Pr->SiS_RVBHCMAX; + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x14,temp); + + temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff; + + tempcx = SiS_Pr->SiS_VGAHT - 1; + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x16,temp); + + temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff; + temp2 |= temp; + + tempcx = SiS_Pr->SiS_VGAVT - 1; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5; + + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x17,temp); + + temp = temp2 | ((tempcx & 0xFF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x15,temp); + + tempbx = SiS_Pr->SiS_VGAHDE; + if(modeflag & HalfDCLK) tempbx >>= 1; + + temp = 0xA0; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + temp = 0; + if(tempbx > 800) { + temp = 0xA0; + if(tempbx != 1024) { + temp = 0xC0; + if(tempbx != 1280) temp = 0; + } + } + } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(tempbx <= 800) { + temp = 0x80; + } + } else { + temp = 0x80; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + temp = 0; + if(tempbx > 800) temp = 0x60; + } + } + if(SiS_Pr->SiS_HiVision & 0x03) { + temp = 0; + if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20; + } + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0; + } + + if(SiS_Pr->SiS_VBType & VB_SIS301) { + if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) + temp |= 0x0A; + } + + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp); + + tempebx = SiS_Pr->SiS_VDE; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { + if(!(temp & 0xE0)) tempebx >>=1; + } + + tempcx = SiS_Pr->SiS_RVBHRS; + temp = tempcx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x18,temp); + + tempeax = SiS_Pr->SiS_VGAVDE; + tempcx |= 0x4000; + if(tempeax <= tempebx) { + tempcx ^= 0x4000; + } else { + tempeax -= tempebx; + } + + templong = (tempeax * 256 * 1024) % tempebx; + tempeax = (tempeax * 256 * 1024) / tempebx; + tempebx = tempeax; + if(templong != 0) tempebx++; + + temp = (USHORT)(tempebx & 0x000000FF); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1B,temp); + temp = (USHORT)((tempebx & 0x0000FF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1A,temp); + + tempbx = (USHORT)(tempebx >> 16); + temp = tempbx & 0x00FF; + temp <<= 4; + temp |= ((tempcx & 0xFF00) >> 8); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x19,temp); + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1C,0x28); + tempbx = 0; + tempax = SiS_Pr->SiS_VGAHDE; + if(modeflag & HalfDCLK) tempax >>= 1; + if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1; + else if(tempax > 800) tempax -= 800; + } else { + if(tempax > 800) tempax -= 800; + } + } + +/* if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) { */ + if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) { + if(tempax > 800) { + tempbx = 8; + if(tempax == 1024) + tempax *= 25; + else + tempax *= 20; + + temp = tempax % 32; + tempax /= 32; + tempax--; + if (temp!=0) tempax++; + } + } + tempax--; + temp = (tempax & 0xFF00) >> 8; + temp &= 0x03; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* From 1.10.7w */ + if(ModeNo > 0x13) { /* From 1.10.7w */ + if(resinfo == SIS_RI_1024x768) tempax = 0x1f; /* From 1.10.7w */ + } /* From 1.10.7w */ + } /* From 1.10.7w */ + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF); + temp <<= 4; + temp |= tempbx; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp); + + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + if(IS_SIS550650740660) { + temp = 0x0026; /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */ + } else { + temp = 0x0036; + } + } else { + temp = 0x0036; + } + if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && + (!(SiS_Pr->SiS_HiVision & 0x03))) { + temp |= 0x01; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) + temp &= 0xFE; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp); + + tempbx = SiS_Pr->SiS_HT; + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1; + } + tempbx >>= 1; + tempbx -= 2; + temp = ((tempbx & 0x0700) >> 8) << 3; + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp); + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp); + + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e); + /* LCD-too-dark-error-source, see FinalizeLCD() */ + } + } + + if(HwDeviceExtension->jChipType >= SIS_315H) { + /* 650/LV BIOS does this for all bridge types - assumingly wrong */ + /* 315, 330, 650+301B BIOS don't do this at all */ + /* This is a duplicate; done for LCDA as well (see above) */ + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) { + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c); + } + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); + } + } else if(HwDeviceExtension->jChipType == SIS_300) { + /* 300/301LV BIOS does this for all bridge types - assumingly wrong */ + if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); + } + } + + } /* 301B */ + + SiS_SetCRT2VCLK(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); +} + + +void +SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT vclkindex; + USHORT temp, reg1, reg2; + + if(SiS_Pr->UseCustomMode) { + reg1 = SiS_Pr->CSR2B; + reg2 = SiS_Pr->CSR2C; + } else { + vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + HwDeviceExtension); + reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A; + reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B; + } + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2); + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { + if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6); + } + } + } + } + } + } else { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1); + } + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00); + temp = 0x08; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20; + SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp); +} + +USHORT +SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempbx; + const USHORT LCDXlat0VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40}; + const USHORT LVDSXlat1VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40}; + const USHORT LVDSXlat4VCLK[4] = {VCLK28, VCLK28, VCLK28, VCLK28}; +#ifdef SIS300 + const USHORT LCDXlat1VCLK300[4] = {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300}; + const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300}; + const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300}; + const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300}; +#endif +#ifdef SIS315H + const USHORT LCDXlat1VCLK310[4] = {VCLK65_315, VCLK65_315, VCLK65_315, VCLK65_315}; + const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315}; + const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315, VCLK65_315, VCLK65_315, VCLK65_315}; + const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315}; +#endif + USHORT CRT2Index,VCLKIndex=0; + USHORT modeflag,resinfo; + const UCHAR *CHTVVCLKPtr = NULL; + const USHORT *LCDXlatVCLK1 = NULL; + const USHORT *LCDXlatVCLK2 = NULL; + const USHORT *LVDSXlatVCLK2 = NULL; + const USHORT *LVDSXlatVCLK3 = NULL; + + if(HwDeviceExtension->jChipType >= SIS_315H) { +#ifdef SIS315H + LCDXlatVCLK1 = LCDXlat1VCLK310; + LCDXlatVCLK2 = LCDXlat2VCLK310; + LVDSXlatVCLK2 = LVDSXlat2VCLK310; + LVDSXlatVCLK3 = LVDSXlat3VCLK310; +#endif + } else { +#ifdef SIS300 + LCDXlatVCLK1 = LCDXlat1VCLK300; + LCDXlatVCLK2 = LCDXlat2VCLK300; + LVDSXlatVCLK2 = LVDSXlat2VCLK300; + LVDSXlatVCLK3 = LVDSXlat3VCLK300; +#endif + } + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { /* 30x/B/LV */ + + if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { + + CRT2Index >>= 6; + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */ + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) { + VCLKIndex = LCDXlat0VCLK[CRT2Index]; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + VCLKIndex = LCDXlatVCLK1[CRT2Index]; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) { + VCLKIndex = LCDXlatVCLK1[CRT2Index]; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) { + VCLKIndex = LCDXlatVCLK1[CRT2Index]; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) { + VCLKIndex = VCLK81_300; /* guessed */ + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) { + VCLKIndex = VCLK108_3_300; + if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300; + } else { + VCLKIndex = LCDXlatVCLK2[CRT2Index]; + } + } else { + if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || + (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + VCLKIndex = VCLK108_2_315; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) { + VCLKIndex = VCLK81_315; /* guessed */ + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + VCLKIndex = VCLK108_2_315; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + VCLKIndex = VCLK162_315; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) { + VCLKIndex = VCLK108_3_315; + if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + VCLKIndex = LCDXlatVCLK1[CRT2Index]; + } else { + VCLKIndex = LCDXlatVCLK2[CRT2Index]; + } + } else { + VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02)); /* Port 3cch */ + VCLKIndex = ((VCLKIndex >> 2) & 0x03); + if(ModeNo > 0x13) { + VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + } + if(ModeNo <= 0x13) { + if(HwDeviceExtension->jChipType <= SIS_315PRO) { + if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42; + } else { + if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00; + } + } + if(HwDeviceExtension->jChipType <= SIS_315PRO) { + if(VCLKIndex == 0) VCLKIndex = 0x41; + if(VCLKIndex == 1) VCLKIndex = 0x43; + if(VCLKIndex == 4) VCLKIndex = 0x44; + } + } + } + } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */ + if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && + (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) { + if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2; + else VCLKIndex = HiTVVCLK; + if(SiS_Pr->SiS_SetFlag & TVSimuMode) { + if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK; + else VCLKIndex = HiTVTextVCLK; + } + } else { + if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO) VCLKIndex = TVVCLKDIV2; + else VCLKIndex = TVVCLK; + } + if(HwDeviceExtension->jChipType < SIS_315H) { + VCLKIndex += TVCLKBASE_300; + } else { + VCLKIndex += TVCLKBASE_315; + } + } else { /* RAMDAC2 */ + VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02)); + VCLKIndex = ((VCLKIndex >> 2) & 0x03); + if(ModeNo > 0x13) { + VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + if(HwDeviceExtension->jChipType < SIS_315H) { + VCLKIndex &= 0x3f; + if( (HwDeviceExtension->jChipType == SIS_630) && + (HwDeviceExtension->jChipRevision >= 0x30)) { + /* This is certainly wrong: It replaces clock + * 108 by 47... + */ + /* if(VCLKIndex == 0x14) VCLKIndex = 0x2e; */ + if(VCLKIndex == 0x14) VCLKIndex = 0x34; + } + } + } + } + + } else { /* If not programming CRT2 */ + + VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02)); + VCLKIndex = ((VCLKIndex >> 2) & 0x03); + if(ModeNo > 0x13) { + VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + if(HwDeviceExtension->jChipType < SIS_315H) { + VCLKIndex &= 0x3f; + if( (HwDeviceExtension->jChipType != SIS_630) && + (HwDeviceExtension->jChipType != SIS_300) ) { + if(VCLKIndex == 0x1b) VCLKIndex = 0x35; + } + } + } + } + + } else { /* LVDS */ + + VCLKIndex = CRT2Index; + + if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { /* programming CRT2 */ + + if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) { + + VCLKIndex &= 0x1f; + tempbx = 0; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1; + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + tempbx += 2; + if(SiS_Pr->SiS_ModeType > ModeVGA) { + if(SiS_Pr->SiS_CHSOverScan) tempbx = 8; + } + if(SiS_Pr->SiS_CHPALM) { + tempbx = 4; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1; + } else if(SiS_Pr->SiS_CHPALN) { + tempbx = 6; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1; + } + } + switch(tempbx) { + case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break; + case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break; + case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break; + case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; + case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break; + case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break; + case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break; + case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break; + case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break; + default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; + } + VCLKIndex = CHTVVCLKPtr[VCLKIndex]; + + } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + + VCLKIndex >>= 6; + if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480)) + VCLKIndex = LVDSXlat1VCLK[VCLKIndex]; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 || + SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) + VCLKIndex = LVDSXlat4VCLK[VCLKIndex]; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) + VCLKIndex = LVDSXlatVCLK2[VCLKIndex]; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) + VCLKIndex = LVDSXlatVCLK2[VCLKIndex]; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) + VCLKIndex = LVDSXlatVCLK2[VCLKIndex]; + else VCLKIndex = LVDSXlatVCLK3[VCLKIndex]; + + if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { + /* Special Timing: Barco iQ Pro R300/400/... */ + VCLKIndex = 0x44; + } + + if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { + if(HwDeviceExtension->jChipType < SIS_315H) { + VCLKIndex = VCLK34_300; + /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ + } else { + VCLKIndex = VCLK34_315; + /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ + } + } + + } else { + + VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02)); + VCLKIndex = ((VCLKIndex >> 2) & 0x03); + if(ModeNo > 0x13) { + VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + if(HwDeviceExtension->jChipType < SIS_315H) { + VCLKIndex &= 0x3F; + } + if( (HwDeviceExtension->jChipType == SIS_630) && + (HwDeviceExtension->jChipRevision >= 0x30) ) { + if(VCLKIndex == 0x14) VCLKIndex = 0x2e; + } + } + } + + } else { /* if not programming CRT2 */ + + VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02)); + VCLKIndex = ((VCLKIndex >> 2) & 0x03); + if(ModeNo > 0x13) { + VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + if(HwDeviceExtension->jChipType < SIS_315H) { + VCLKIndex &= 0x3F; + if( (HwDeviceExtension->jChipType != SIS_630) && + (HwDeviceExtension->jChipType != SIS_300) ) { + if(VCLKIndex == 0x1b) VCLKIndex = 0x35; + } +#if 0 + if(HwDeviceExtension->jChipType == SIS_730) { + if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */ + if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */ + } +#endif + } + } + + } + + } +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex); +#endif + return(VCLKIndex); +} + +/* Set 301 Palette address port registers */ +/* Checked against 650/301LV BIOS */ +void +SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr, + UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex) +{ + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; + + if(SiS_Pr->SiS_ModeType == ModeVGA) { + if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){ + SiS_EnableCRT2(SiS_Pr); + SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex); + } + } +} + +void +SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp,tempah,i,modeflag,j; + USHORT ResIndex,DisplayType; + const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + + if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || + (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || + (SiS_Pr->SiS_CustomT == CUT_PANEL848)) + return; + + temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, + &ResIndex,&DisplayType); + + if(temp == 0) return; + + if(HwDeviceExtension->jChipType < SIS_315H) { + if(SiS_Pr->SiS_SetFlag & SetDOSMode) return; + } + + switch(DisplayType) { + case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break; + case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break; + case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break; + case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break; + case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break; + case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break; + case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break; + case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break; + case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break; + case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break; + case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break; + case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break; + case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break; + case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break; + case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break; + case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break; + case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break; + case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break; + case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break; + case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break; + case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break; + case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break; + case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */ + case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break; + case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break; + case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break; + case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break; + case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break; + case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break; + case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break; + case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break; + case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break; + case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break; + case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break; + case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break; + case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break; + case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break; + case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break; + case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break; + case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break; + case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break; + case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break; + case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break; + case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break; + case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break; + case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break; + default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break; + } + + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /*unlock cr0-7 */ + + tempah = (LVDSCRT1Ptr + ResIndex)->CR[0]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah); + + for(i=0x02,j=1;i<=0x05;i++,j++){ + tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); + } + for(i=0x06,j=5;i<=0x07;i++,j++){ + tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); + } + for(i=0x10,j=7;i<=0x11;i++,j++){ + tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); + } + for(i=0x15,j=9;i<=0x16;i++,j++){ + tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); + } + for(i=0x0A,j=11;i<=0x0C;i++,j++){ + tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah); + } + + tempah = (LVDSCRT1Ptr + ResIndex)->CR[14]; + tempah &= 0xE0; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah); + + tempah = (LVDSCRT1Ptr + ResIndex)->CR[14]; + tempah &= 0x01; + tempah <<= 5; + if(modeflag & DoubleScanMode) tempah |= 0x080; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah); + + /* 650/LVDS BIOS - doesn't make sense */ + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(modeflag & HalfDCLK) + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); + } +} + +BOOLEAN +SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *ResIndex, + USHORT *DisplayType) + { + USHORT tempbx,modeflag=0; + USHORT Flag,CRT2CRTC; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0; + } + } else { + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0; + } + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } + + Flag = 1; + tempbx = 0; + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { + Flag = 0; + tempbx = 18; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++; + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + tempbx += 2; + if(SiS_Pr->SiS_ModeType > ModeVGA) { + if(SiS_Pr->SiS_CHSOverScan) tempbx = 99; + } + if(SiS_Pr->SiS_CHPALM) { + tempbx = 18; /* PALM uses NTSC data */ + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++; + } else if(SiS_Pr->SiS_CHPALN) { + tempbx = 20; /* PALN uses PAL data */ + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++; + } + } + } + } + if(Flag) { + tempbx = SiS_Pr->SiS_LCDResInfo; + tempbx -= SiS_Pr->SiS_PanelMinLVDS; + if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) { + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 6; + if(modeflag & HalfDCLK) tempbx += 3; + } else { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + tempbx = 14; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2; + if(modeflag & HalfDCLK) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) { + tempbx = 23; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2; + if(modeflag & HalfDCLK) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) { + tempbx = 27; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2; + if(modeflag & HalfDCLK) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + tempbx = 36; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2; + if(modeflag & HalfDCLK) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) { + tempbx = 40; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2; + if(modeflag & HalfDCLK) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) { + tempbx = 54; + if(modeflag & HalfDCLK) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) { + tempbx = 52; + if(modeflag & HalfDCLK) tempbx++; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { + tempbx = 50; + if(modeflag & HalfDCLK) tempbx++; + } + + } + if(SiS_Pr->SiS_LCDInfo & LCDPass11) { + tempbx = 12; + if(modeflag & HalfDCLK) tempbx++; + } + } + +#if 0 + if(SiS_Pr->SiS_IF_DEF_FSTN) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){ + tempbx = 22; + } + } +#endif + + *ResIndex = CRT2CRTC & 0x3F; + *DisplayType = tempbx; + return 1; +} + +void +SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT clkbase, vclkindex=0; + UCHAR sr2b, sr2c; + + if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) { + SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); + if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) { + RefreshRateTableIndex--; + } + vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; + } else { + vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + } + + sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B; + sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C; + + if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(ROMAddr[0x220] & 0x01) { + sr2b = ROMAddr[0x227]; + sr2c = ROMAddr[0x228]; + } + } + } + + clkbase = 0x02B; + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { + clkbase += 3; + } + } + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20); + SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b); + SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10); + SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b); + SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00); + SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b); + SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); +} + +#if 0 /* Not used */ +void +SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr) +{ + USHORT temp; + + if(SiS_Pr->SiS_IF_DEF_LVDS==0) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x40); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,0x80); + temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + temp &= 0xC3; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,temp); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x02); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x00); + } +} +#endif + +/* Start of Chrontel 70xx functions ---------------------- */ + +/* Set-up the Chrontel Registers */ +void +SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex) +{ + USHORT temp, tempbx, tempcl; + USHORT TVType, resindex; + const SiS_CHTVRegDataStruct *CHTVRegData = NULL; + + if(ModeNo <= 0x13) + tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + else + tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + + TVType = 0; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1; + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + TVType += 2; + if(SiS_Pr->SiS_ModeType > ModeVGA) { + if(SiS_Pr->SiS_CHSOverScan) TVType = 8; + } + if(SiS_Pr->SiS_CHPALM) { + TVType = 4; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1; + } else if(SiS_Pr->SiS_CHPALN) { + TVType = 6; + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1; + } + } + switch(TVType) { + case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break; + case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break; + case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break; + case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; + case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break; + case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break; + case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break; + case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break; + case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break; + default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; + } + resindex = tempcl & 0x3F; + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { + +#ifdef SIS300 + + /* Chrontel 7005 - I assume that it does not come with a 315 series chip */ + + /* We don't support modes >800x600 */ + if (resindex > 5) return; + + if(SiS_Pr->SiS_VBInfo & SetPALTV) { + SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/ + SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/ + } else { + SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/ + SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/ + } + + temp = CHTVRegData[resindex].Reg[0]; + tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */ + SiS_SetCH700x(SiS_Pr,tempbx); + temp = CHTVRegData[resindex].Reg[1]; + tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */ + SiS_SetCH700x(SiS_Pr,tempbx); + temp = CHTVRegData[resindex].Reg[2]; + tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */ + SiS_SetCH700x(SiS_Pr,tempbx); + temp = CHTVRegData[resindex].Reg[3]; + tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */ + SiS_SetCH700x(SiS_Pr,tempbx); + temp = CHTVRegData[resindex].Reg[4]; + tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */ + SiS_SetCH700x(SiS_Pr,tempbx); + + /* Set minimum flicker filter for Luma channel (SR1-0=00), + minimum text enhancement (S3-2=10), + maximum flicker filter for Chroma channel (S5-4=10) + =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!) + */ + SiS_SetCH700x(SiS_Pr,0x2801); + + /* Set video bandwidth + High bandwith Luma composite video filter(S0=1) + low bandwith Luma S-video filter (S2-1=00) + disable peak filter in S-video channel (S3=0) + high bandwidth Chroma Filter (S5-4=11) + =00110001=0x31 + */ + SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */ + + /* Register 0x3D does not exist in non-macrovision register map + (Maybe this is a macrovision register?) + */ +#ifndef SIS_CP + SiS_SetCH70xx(SiS_Pr,0x003D); +#endif + + /* Register 0x10 only contains 1 writable bit (S0) for sensing, + all other bits a read-only. Macrovision? + */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F); + + /* Register 0x11 only contains 3 writable bits (S0-S2) for + contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) ) + */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8); + + /* Clear DSEN + */ + SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF); + + if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { /* ---- NTSC ---- */ + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) { + if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */ + } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */ + } + } else { + if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); + } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */ +#if 0 + SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0); + SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */ +#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); + } + } + } else { /* ---- PAL ---- */ + /* We don't play around with FSCI in PAL mode */ + if (resindex == 0x04) { + SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */ + } else { + SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ + SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */ + } + } + +#endif /* 300 */ + + } else { + + /* Chrontel 7019 - assumed that it does not come with a 300 series chip */ + +#ifdef SIS315H + + /* We don't support modes >1024x768 */ + if (resindex > 6) return; + + temp = CHTVRegData[resindex].Reg[0]; + tempbx=((temp & 0x00FF) <<8 ) | 0x00; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[1]; + tempbx=((temp & 0x00FF) <<8 ) | 0x01; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[2]; + tempbx=((temp & 0x00FF) <<8 ) | 0x02; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[3]; + tempbx=((temp & 0x00FF) <<8 ) | 0x04; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[4]; + tempbx=((temp & 0x00FF) <<8 ) | 0x03; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[5]; + tempbx=((temp & 0x00FF) <<8 ) | 0x05; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[6]; + tempbx=((temp & 0x00FF) <<8 ) | 0x06; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[7]; + tempbx=((temp & 0x00FF) <<8 ) | 0x07; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[8]; + tempbx=((temp & 0x00FF) <<8 ) | 0x08; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[9]; + tempbx=((temp & 0x00FF) <<8 ) | 0x15; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[10]; + tempbx=((temp & 0x00FF) <<8 ) | 0x1f; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[11]; + tempbx=((temp & 0x00FF) <<8 ) | 0x0c; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[12]; + tempbx=((temp & 0x00FF) <<8 ) | 0x0d; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[13]; + tempbx=((temp & 0x00FF) <<8 ) | 0x0e; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[14]; + tempbx=((temp & 0x00FF) <<8 ) | 0x0f; + SiS_SetCH701x(SiS_Pr,tempbx); + + temp = CHTVRegData[resindex].Reg[15]; + tempbx=((temp & 0x00FF) <<8 ) | 0x10; + SiS_SetCH701x(SiS_Pr,tempbx); + +#endif /* 315 */ + + } + +#ifdef SIS_CP + SIS_CP_INIT301_CP3 +#endif + +} + +/* Chrontel 701x functions ================================= */ + +void +SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp; + + /* Enable Chrontel 7019 LCD panel backlight */ + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + if(HwDeviceExtension->jChipType == SIS_740) { + SiS_SetCH701x(SiS_Pr,0x6566); + } else { + temp = SiS_GetCH701x(SiS_Pr,0x66); + temp |= 0x20; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); + } + } +} + +void +SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr) +{ + USHORT temp; + + /* Disable Chrontel 7019 LCD panel backlight */ + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + temp = SiS_GetCH701x(SiS_Pr,0x66); + temp &= 0xDF; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); + } +} + +#ifdef SIS315H /* ----------- 315 series only ---------- */ + +void +SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr) +{ + UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 }; + UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, + 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 }; + UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, + 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; + UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, + 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; + UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, + 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 }; + UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, + 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 }; + UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, + 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 }; + UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef, + 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 }; + UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, + 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a }; + UCHAR *tableptr = NULL; + USHORT tempbh; + int i; + + if(HwDeviceExtension->jChipType == SIS_740) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + tableptr = table1024_740; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + tableptr = table1280_740; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + tableptr = table1400_740; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + tableptr = table1600_740; + } else return; + } else { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + tableptr = table1024_650; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + tableptr = table1280_650; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + tableptr = table1400_650; + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) { + tableptr = table1600_650; + } else return; + } + + tempbh = SiS_GetCH701x(SiS_Pr,0x74); + if((tempbh == 0xf6) || (tempbh == 0xc7)) { + tempbh = SiS_GetCH701x(SiS_Pr,0x73); + if(tempbh == 0xc8) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) return; + } else if(tempbh == 0xdb) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) return; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return; + } else if(tempbh == 0xde) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return; + } + } + + if(HwDeviceExtension->jChipType == SIS_740) { + tempbh = 0x0d; + } else { + tempbh = 0x0c; + } + for(i = 0; i < tempbh; i++) { + SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]); + } + SiS_ChrontelPowerSequencing(SiS_Pr,HwDeviceExtension); + tempbh = SiS_GetCH701x(SiS_Pr,0x1e); + tempbh |= 0xc0; + SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e); + + if(HwDeviceExtension->jChipType == SIS_740) { + tempbh = SiS_GetCH701x(SiS_Pr,0x1c); + tempbh &= 0xfb; + SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03); + tempbh = SiS_GetCH701x(SiS_Pr,0x64); + tempbh |= 0x40; + SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64); + tempbh = SiS_GetCH701x(SiS_Pr,0x03); + tempbh &= 0x3f; + SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03); + } +} + +void +SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b }; + UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 }; + UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 }; + UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; + UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; + UCHAR *tableptr = NULL; + int i; + + /* Set up Power up/down timing */ + + if(HwDeviceExtension->jChipType == SIS_740) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + tableptr = table1024_740; + } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) { + tableptr = table1400_740; + } else return; + } else { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + tableptr = table1024_650; + } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) || + (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) { + tableptr = table1400_650; + } else return; + } + + for(i=0; i<5; i++) { + SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]); + } +} + +void +SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr) +{ + USHORT temp; + + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + if(HwDeviceExtension->jChipType == SIS_740) { + temp = SiS_GetCH701x(SiS_Pr,0x1c); + temp |= 0x04; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c); + } + if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) { + temp = SiS_GetCH701x(SiS_Pr,0x01); + temp &= 0x3f; + temp |= 0x80; /* Enable YPrPb (HDTV) */ + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01); + } + if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) { + temp = SiS_GetCH701x(SiS_Pr,0x01); + temp &= 0x3f; + temp |= 0xc0; /* Enable SCART + CVBS */ + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01); + } + if(HwDeviceExtension->jChipType == SIS_740) { + SiS_ChrontelDoSomething5(SiS_Pr); + SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */ + } else { + SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */ + temp = SiS_GetCH701x(SiS_Pr,0x49); + if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) { + temp = SiS_GetCH701x(SiS_Pr,0x73); + temp |= 0x60; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73); + } + temp = SiS_GetCH701x(SiS_Pr,0x47); + temp &= 0x7f; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); + SiS_LongDelay(SiS_Pr,2); + temp = SiS_GetCH701x(SiS_Pr,0x47); + temp |= 0x80; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); + } + } +} + +void +SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp; + + /* Complete power down of LVDS */ + if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { + if(HwDeviceExtension->jChipType == SIS_740) { + SiS_LongDelay(SiS_Pr,1); + SiS_GenericDelay(SiS_Pr,0x16ff); + SiS_SetCH701x(SiS_Pr,0xac76); + SiS_SetCH701x(SiS_Pr,0x0066); + } else { + SiS_LongDelay(SiS_Pr,2); + temp = SiS_GetCH701x(SiS_Pr,0x76); + temp &= 0xfc; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); + SiS_SetCH701x(SiS_Pr,0x0066); + } + } +} + +void +SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr) +{ + unsigned char temp, temp1; + + temp1 = SiS_GetCH701x(SiS_Pr,0x49); + SiS_SetCH701x(SiS_Pr,0x3e49); + temp = SiS_GetCH701x(SiS_Pr,0x47); + temp &= 0x7f; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); + SiS_LongDelay(SiS_Pr,3); + temp = SiS_GetCH701x(SiS_Pr,0x47); + temp |= 0x80; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); + SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49); +} + +void +SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ + USHORT temp; + + if(HwDeviceExtension->jChipType == SIS_740) { + temp = SiS_GetCH701x(SiS_Pr,0x4a); + temp &= 0x01; + if(!(temp)) { + + if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) { + temp = SiS_GetCH701x(SiS_Pr,0x49); + SiS_SetCH701x(SiS_Pr,0x3e49); + } + /* Reset Chrontel 7019 datapath */ + SiS_SetCH701x(SiS_Pr,0x1048); + SiS_LongDelay(SiS_Pr,1); + SiS_SetCH701x(SiS_Pr,0x1848); + + if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_ChrontelDoSomething5(SiS_Pr); + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49); + } + + } else { + + temp = SiS_GetCH701x(SiS_Pr,0x5c); + temp &= 0xef; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c); + temp = SiS_GetCH701x(SiS_Pr,0x5c); + temp |= 0x10; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c); + temp = SiS_GetCH701x(SiS_Pr,0x5c); + temp &= 0xef; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c); + temp = SiS_GetCH701x(SiS_Pr,0x61); + if(!temp) { + SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr); + } + } + } else { /* 650 */ + /* Reset Chrontel 7019 datapath */ + SiS_SetCH701x(SiS_Pr,0x1048); + SiS_LongDelay(SiS_Pr,1); + SiS_SetCH701x(SiS_Pr,0x1848); + } +} + +void +SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ + USHORT temp; + + if(HwDeviceExtension->jChipType == SIS_740) { + + if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_ChrontelDoSomething5(SiS_Pr); + } + + } else { + + SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */ + temp = SiS_GetCH701x(SiS_Pr,0x49); + temp &= 1; + if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */ + temp = SiS_GetCH701x(SiS_Pr,0x47); + temp &= 0x70; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */ + SiS_LongDelay(SiS_Pr,3); + temp = SiS_GetCH701x(SiS_Pr,0x47); + temp |= 0x80; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */ + } + + } +} + +void +SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT BaseAddr) +{ + USHORT temp,temp1; + + if(HwDeviceExtension->jChipType == SIS_740) { + + temp = SiS_GetCH701x(SiS_Pr,0x61); + if(temp < 1) { + temp++; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61); + } + SiS_SetCH701x(SiS_Pr,0x4566); + SiS_SetCH701x(SiS_Pr,0xaf76); + SiS_LongDelay(SiS_Pr,1); + SiS_GenericDelay(SiS_Pr,0x16ff); + + } else { /* 650 */ + + temp1 = 0; + temp = SiS_GetCH701x(SiS_Pr,0x61); + if(temp < 2) { + temp++; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61); + temp1 = 1; + } + SiS_SetCH701x(SiS_Pr,0xac76); + temp = SiS_GetCH701x(SiS_Pr,0x66); + temp |= 0x5f; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); + if(ModeNo > 0x13) { + if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_GenericDelay(SiS_Pr,0x3ff); + } else { + SiS_GenericDelay(SiS_Pr,0x2ff); + } + } else { + if(!temp1) + SiS_GenericDelay(SiS_Pr,0x2ff); + } + temp = SiS_GetCH701x(SiS_Pr,0x76); + temp |= 0x03; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); + temp = SiS_GetCH701x(SiS_Pr,0x66); + temp &= 0x7f; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); + SiS_LongDelay(SiS_Pr,1); + + } +} + +void +SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ + USHORT temp,tempcl,tempch; + + SiS_LongDelay(SiS_Pr, 1); + tempcl = 3; + tempch = 0; + + do { + temp = SiS_GetCH701x(SiS_Pr,0x66); + temp &= 0x04; + if(temp == 0x04) break; + + if(HwDeviceExtension->jChipType == SIS_740) { + SiS_SetCH701x(SiS_Pr,0xac76); + } + + SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr); + + if(tempcl == 0) { + if(tempch == 3) break; + SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr); + tempcl = 3; + tempch++; + } + tempcl--; + temp = SiS_GetCH701x(SiS_Pr,0x76); + temp &= 0xfb; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); + SiS_LongDelay(SiS_Pr,2); + temp = SiS_GetCH701x(SiS_Pr,0x76); + temp |= 0x04; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); + if(HwDeviceExtension->jChipType == SIS_740) { + SiS_SetCH701x(SiS_Pr,0xe078); + } else { + SiS_SetCH701x(SiS_Pr,0x6078); + } + SiS_LongDelay(SiS_Pr,2); + } while(0); + + SiS_SetCH701x(SiS_Pr,0x0077); +} + +void +SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT BaseAddr) +{ + USHORT temp; + + temp = SiS_GetCH701x(SiS_Pr,0x03); + temp |= 0x80; /* Set datapath 1 to TV */ + temp &= 0xbf; /* Set datapath 2 to LVDS */ + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03); + + if(HwDeviceExtension->jChipType == SIS_740) { + + temp = SiS_GetCH701x(SiS_Pr,0x1c); + temp &= 0xfb; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c); + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03); + + temp = SiS_GetCH701x(SiS_Pr,0x64); + temp |= 0x40; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64); + + temp = SiS_GetCH701x(SiS_Pr,0x03); + temp &= 0x3f; + SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03); + + temp = SiS_GetCH701x(SiS_Pr,0x66); + if(temp != 0x45) { + SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr); + SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr); + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34); + SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr); + } + + } else { /* 650 */ + + SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr); + + SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr); + + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34); + SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr); + + SiS_SetCH701x(SiS_Pr,0xaf76); + + } + +} + +#endif /* 315 series ------------------------------------ */ + +/* End of Chrontel 701x functions ==================================== */ + +/* Generic Read/write routines for Chrontel ========================== */ + +/* The Chrontel is connected to the 630/730 via + * the 630/730's DDC/I2C port. + * + * On 630(S)T chipset, the index changed from 0x11 to 0x0a, + * possibly for working around the DDC problems + */ + +void +SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) +{ + if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) + SiS_SetCH700x(SiS_Pr,tempbx); + else + SiS_SetCH701x(SiS_Pr,tempbx); +} + +/* Write to Chrontel 700x */ +/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */ +void +SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx) +{ + USHORT tempah,temp,i; + + if(!(SiS_Pr->SiS_ChrontelInit)) { + SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ + SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ + SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ + SiS_Pr->SiS_DDC_DataShift = 0x00; + SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ + } + + for(i=0;i<10;i++) { /* Do only 10 attempts to write */ + /* SiS_SetSwitchDDC2(SiS_Pr); */ + if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = tempbx & 0x00FF; /* Write RAB */ + tempah |= 0x80; /* (set bit 7, see datasheet) */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); + if(temp) continue; /* (ERROR: no ack) */ + tempah = (tempbx & 0xFF00) >> 8; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */ + if(temp) continue; /* (ERROR: no ack) */ + if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */ + SiS_Pr->SiS_ChrontelInit = 1; + return; + } + + /* For 630ST */ + if(!(SiS_Pr->SiS_ChrontelInit)) { + SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */ + SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */ + SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */ + SiS_Pr->SiS_DDC_DataShift = 0x00; + SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ + + for(i=0;i<10;i++) { /* Do only 10 attempts to write */ + /* SiS_SetSwitchDDC2(SiS_Pr); */ + if (SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = tempbx & 0x00FF; /* Write RAB */ + tempah |= 0x80; /* (set bit 7, see datasheet) */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); + if(temp) continue; /* (ERROR: no ack) */ + tempah = (tempbx & 0xFF00) >> 8; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */ + if(temp) continue; /* (ERROR: no ack) */ + if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */ + SiS_Pr->SiS_ChrontelInit = 1; + return; + } + } +} + +/* Write to Chrontel 701x */ +/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */ +void +SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx) +{ + USHORT tempah,temp,i; + + SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ + SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ + SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ + SiS_Pr->SiS_DDC_DataShift = 0x00; + SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ + + for(i=0;i<10;i++) { /* Do only 10 attempts to write */ + if (SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = tempbx & 0x00FF; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write RAB */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = (tempbx & 0xFF00) >> 8; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */ + if(temp) continue; /* (ERROR: no ack) */ + if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */ + return; + } +} + +/* Read from Chrontel 70xx */ +/* Parameter is [Register no (S7-S0)] */ +USHORT +SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) +{ + if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) + return(SiS_GetCH700x(SiS_Pr,tempbx)); + else + return(SiS_GetCH701x(SiS_Pr,tempbx)); +} + +/* Read from Chrontel 700x */ +/* Parameter is [Register no (S7-S0)] */ +USHORT +SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx) +{ + USHORT tempah,temp,i; + + if(!(SiS_Pr->SiS_ChrontelInit)) { + SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ + SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ + SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ + SiS_Pr->SiS_DDC_DataShift = 0x00; + SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ + } + + SiS_Pr->SiS_DDC_ReadAddr = tempbx; + + for(i=0;i<20;i++) { /* Do only 20 attempts to read */ + /* SiS_SetSwitchDDC2(SiS_Pr); */ + if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* Write RAB | 0x80 */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); + if(temp) continue; /* (ERROR: no ack) */ + if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */ + if (SiS_SetStop(SiS_Pr)) continue; /* Stop condition */ + SiS_Pr->SiS_ChrontelInit = 1; + return(tempah); + } + + /* For 630ST */ + if(!SiS_Pr->SiS_ChrontelInit) { + SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 0 = SC; Bit 1 = SD */ + SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */ + SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */ + SiS_Pr->SiS_DDC_DataShift = 0x00; + SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ + + for(i=0;i<20;i++) { /* Do only 20 attempts to read */ + /* SiS_SetSwitchDDC2(SiS_Pr); */ + if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* Write RAB | 0x80 */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); + if(temp) continue; /* (ERROR: no ack) */ + if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */ + if (SiS_SetStop(SiS_Pr)) continue; /* Stop condition */ + SiS_Pr->SiS_ChrontelInit = 1; + return(tempah); + } + } + return(0xFFFF); +} + +/* Read from Chrontel 701x */ +/* Parameter is [Register no (S7-S0)] */ +USHORT +SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx) +{ + USHORT tempah,temp,i; + + SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ + SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ + SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ + SiS_Pr->SiS_DDC_DataShift = 0x00; + SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ + SiS_Pr->SiS_DDC_ReadAddr = tempbx; + + for(i=0;i<20;i++) { /* Do only 20 attempts to read */ + if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr; + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = SiS_Pr->SiS_DDC_ReadAddr; /* Write RAB */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); + if(temp) continue; /* (ERROR: no ack) */ + if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */ + tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */ + temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */ + if(temp) continue; /* (ERROR: no ack) */ + tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */ + SiS_SetStop(SiS_Pr); /* Stop condition */ + return(tempah); + } + return 0xFFFF; +} + +/* Our own DDC functions */ +USHORT +SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine, + USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32) +{ + unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 }; + unsigned char flag, cr32; + USHORT temp = 0, myadaptnum = adaptnum; + + if(adaptnum != 0) { + if(!(VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF; + if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF; + } + + /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */ + + SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */ + + SiS_Pr->SiS_DDC_SecAddr = 0; + SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype]; + SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4; + SiS_Pr->SiS_DDC_Index = 0x11; + flag = 0xff; + + cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32); + +#if 0 + if(VBFlags & VB_SISBRIDGE) { + if(myadaptnum == 0) { + if(!(cr32 & 0x20)) { + myadaptnum = 2; + if(!(cr32 & 0x10)) { + myadaptnum = 1; + if(!(cr32 & 0x08)) { + myadaptnum = 0; + } + } + } + } + } +#endif + + if(VGAEngine == SIS_300_VGA) { /* 300 series */ + + if(myadaptnum != 0) { + flag = 0; + if(VBFlags & VB_SISBRIDGE) { + SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; + SiS_Pr->SiS_DDC_Index = 0x0f; + } + } + + if(!(VBFlags & VB_301)) { + if((cr32 & 0x80) && (checkcr32)) { + if(myadaptnum >= 1) { + if(!(cr32 & 0x08)) { + myadaptnum = 1; + if(!(cr32 & 0x10)) return 0xFFFF; + } + } + } + } + + temp = 4 - (myadaptnum * 2); + if(flag) temp = 0; + + } else { /* 315/330 series */ + + /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */ + + if(VBFlags & VB_SISBRIDGE) { + if(myadaptnum == 2) { + myadaptnum = 1; + } + } + + if(myadaptnum == 1) { + flag = 0; + if(VBFlags & VB_SISBRIDGE) { + SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; + SiS_Pr->SiS_DDC_Index = 0x0f; + } + } + + if((cr32 & 0x80) && (checkcr32)) { + if(myadaptnum >= 1) { + if(!(cr32 & 0x08)) { + myadaptnum = 1; + if(!(cr32 & 0x10)) return 0xFFFF; + } + } + } + + temp = myadaptnum; + if(myadaptnum == 1) { + temp = 0; + if(VBFlags & VB_LVDS) flag = 0xff; + } + + if(flag) temp = 0; + } + + SiS_Pr->SiS_DDC_Data = 0x02 << temp; + SiS_Pr->SiS_DDC_Clk = 0x01 << temp; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n", + SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp); +#endif + + return 0; +} + +USHORT +SiS_WriteDABDDC(SiS_Private *SiS_Pr) +{ + if(SiS_SetStart(SiS_Pr)) return 0xFFFF; + if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) { + return 0xFFFF; + } + if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) { + return 0xFFFF; + } + return(0); +} + +USHORT +SiS_PrepareReadDDC(SiS_Private *SiS_Pr) +{ + if(SiS_SetStart(SiS_Pr)) return 0xFFFF; + if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) { + return 0xFFFF; + } + return(0); +} + +USHORT +SiS_PrepareDDC(SiS_Private *SiS_Pr) +{ + if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr); + if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr)); + return(0); +} + +void +SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno) +{ + SiS_SetSCLKLow(SiS_Pr); + if(yesno) { + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data, SiS_Pr->SiS_DDC_Data); + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data, 0); + } + SiS_SetSCLKHigh(SiS_Pr); +} + +USHORT +SiS_DoProbeDDC(SiS_Private *SiS_Pr) +{ + unsigned char mask, value; + USHORT temp, ret=0; + BOOLEAN failed = FALSE; + + SiS_SetSwitchDDC2(SiS_Pr); + if(SiS_PrepareDDC(SiS_Pr)) { + SiS_SetStop(SiS_Pr); + return(0xFFFF); + } + mask = 0xf0; + value = 0x20; + if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { + temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); + SiS_SendACK(SiS_Pr, 0); + if(temp == 0) { + mask = 0xff; + value = 0xff; + } else { + failed = TRUE; + ret = 0xFFFF; + } + } + if(failed == FALSE) { + temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); + SiS_SendACK(SiS_Pr, 1); + temp &= mask; + if(temp == value) ret = 0; + else { + ret = 0xFFFF; + if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { + if(temp == 0x30) ret = 0; + } + } + } + SiS_SetStop(SiS_Pr); + return(ret); +} + +USHORT +SiS_ProbeDDC(SiS_Private *SiS_Pr) +{ + USHORT flag; + + flag = 0x180; + SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; + if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02; + SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; + if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08; + SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; + if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10; + if(!(flag & 0x1a)) flag = 0; + return(flag); +} + +USHORT +SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer) +{ + USHORT flag, length, i; + unsigned char chksum,gotcha; + + if(DDCdatatype > 4) return 0xFFFF; + + flag = 0; + SiS_SetSwitchDDC2(SiS_Pr); + if(!(SiS_PrepareDDC(SiS_Pr))) { + length = 127; + if(DDCdatatype != 1) length = 255; + chksum = 0; + gotcha = 0; + for(i=0; i<length; i++) { + buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); + chksum += buffer[i]; + gotcha |= buffer[i]; + SiS_SendACK(SiS_Pr, 0); + } + buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); + chksum += buffer[i]; + SiS_SendACK(SiS_Pr, 1); + if(gotcha) flag = (USHORT)chksum; + else flag = 0xFFFF; + } else { + flag = 0xFFFF; + } + SiS_SetStop(SiS_Pr); + return(flag); +} + +/* Our private DDC functions + + It complies somewhat with the corresponding VESA function + in arguments and return values. + + Since this is probably called before the mode is changed, + we use our pre-detected pSiS-values instead of SiS_Pr as + regards chipset and video bridge type. + + Arguments: + adaptnum: 0=CRT1, 1=LCD, 2=VGA2 + CRT2 DDC is only supported on SiS301, 301B, 302B. + DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2) + buffer: ptr to 256 data bytes which will be filled with read data. + + Returns 0xFFFF if error, otherwise + if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum) + if DDCdatatype = 0: Returns supported DDC modes + + */ +USHORT +SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine, + USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer) +{ + if(adaptnum > 2) return 0xFFFF; + if(DDCdatatype > 4) return 0xFFFF; + if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF; + if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF; + if(DDCdatatype == 0) { + return(SiS_ProbeDDC(SiS_Pr)); + } else { + return(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)); + } +} + +#ifdef LINUX_XF86 +/* Sense the LCD parameters (CR36, CR37) via DDC */ +/* SiS30x(B) only */ +USHORT +SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) +{ + USHORT DDCdatatype, paneltype, flag, xres=0, yres=0; + USHORT index, myindex, lumsize, numcodes; + unsigned char cr37=0, seekcode; + BOOLEAN checkexpand = FALSE; + int retry, i; + unsigned char buffer[256]; + + for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE; + SiS_Pr->CP_HaveCustomData = FALSE; + SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0; + + if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0; + if(pSiS->VBFlags & VB_30xBDH) return 0; + + if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0; + + SiS_Pr->SiS_DDC_SecAddr = 0x00; + + /* Probe supported DA's */ + flag = SiS_ProbeDDC(SiS_Pr); +#ifdef TWDEBUG + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, + "CRT2 DDC capabilities 0x%x\n", flag); +#endif + if(flag & 0x10) { + SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */ + DDCdatatype = 4; + } else if(flag & 0x08) { + SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */ + DDCdatatype = 3; + } else if(flag & 0x02) { + SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */ + DDCdatatype = 1; + } else return 0; /* no DDC support (or no device attached) */ + + /* Read the entire EDID */ + retry = 2; + do { + if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, + "CRT2: DDC read failed (attempt %d), %s\n", + (3-retry), (retry == 1) ? "giving up" : "retrying"); + retry--; + if(retry == 0) return 0xFFFF; + } else break; + } while(1); + +#ifdef TWDEBUG + for(i=0; i<256; i+=16) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, + "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + buffer[i], buffer[i+1], buffer[i+2], buffer[i+3], + buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7], + buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11], + buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]); + } +#endif + + /* Analyze EDID and retrieve LCD panel information */ + paneltype = 0; + switch(DDCdatatype) { + case 1: /* Analyze EDID V1 */ + /* Catch a few clear cases: */ + if(!(buffer[0x14] & 0x80)) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "CRT2: Attached display expects analog input (0x%02x)\n", + buffer[0x14]); + return 0; + } + + if((buffer[0x18] & 0x18) != 0x08) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "CRT2: Attached display is not of RGB but of %s type (0x%02x)\n", + ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" : + ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" : + "undefined"), + buffer[0x18]); + return 0; + } + + /* Now analyze the first Detailed Timing Block and see + * if the preferred timing mode is stored there. If so, + * check if this is a standard panel for which we already + * know the timing. + */ + + paneltype = Panel_Custom; + checkexpand = FALSE; + + if(buffer[0x18] & 0x02) { + + xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4); + yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4); + + SiS_Pr->CP_PreferredX = xres; + SiS_Pr->CP_PreferredY = yres; + + switch(xres) { + case 800: + if(yres == 600) { + paneltype = Panel_800x600; + checkexpand = TRUE; + } + break; + case 1024: + if(yres == 768) { + paneltype = Panel_1024x768; + checkexpand = TRUE; + } + break; + case 1280: + if(yres == 1024) { + paneltype = Panel_1280x1024; + checkexpand = TRUE; + } else if(yres == 960) { + if(pSiS->VGAEngine == SIS_300_VGA) { + paneltype = Panel300_1280x960; + } else { + paneltype = Panel310_1280x960; + } + } else if(yres == 768) { + paneltype = Panel_1280x768; + checkexpand = FALSE; + cr37 |= 0x10; + } + break; + case 1400: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(yres == 1050) { + paneltype = Panel310_1400x1050; + checkexpand = TRUE; + } + } + break; +#if 0 /* Treat this as custom, as we have no valid timing data yet */ + case 1600: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(yres == 1200) { + paneltype = Panel310_1600x1200; + checkexpand = TRUE; + } + } + break; +#endif + } + + if(paneltype != Panel_Custom) { + if((buffer[0x47] & 0x18) == 0x18) { + cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20); + } else { + /* What now? There is no digital separate output timing... */ + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, + "CRT2: Unable to retrieve Sync polarity information\n"); + } + } + + } + + /* If we still don't know what panel this is, we take it + * as a custom panel and derive the timing data from the + * detailed timing blocks + */ + if(paneltype == Panel_Custom) { + + BOOLEAN havesync = FALSE; + int i, temp, base = 0x36; + unsigned long estpack; + unsigned short estx[] = { + 720, 720, 640, 640, 640, 640, 800, 800, + 800, 800, 832,1024,1024,1024,1024,1280, + 1152 + }; + unsigned short esty[] = { + 400, 400, 480, 480, 480, 480, 600, 600, + 600, 600, 624, 768, 768, 768, 768,1024, + 870 + }; + + paneltype = 0; + + /* Find the maximum resolution */ + + /* 1. From Established timings */ + estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01); + for(i=16; i>=0; i--) { + if(estpack & (1 << i)) { + if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i]; + if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i]; + } + } + + /* 2. From Standard Timings */ + for(i=0x26; i < 0x36; i+=2) { + if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) { + temp = (buffer[i] + 31) * 8; + if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp; + switch((buffer[i+1] & 0xc0) >> 6) { + case 0x03: temp = temp * 9 / 16; break; + case 0x02: temp = temp * 4 / 5; break; + case 0x01: temp = temp * 3 / 4; break; + } + if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp; + } + } + + /* Now extract the Detailed Timings and convert them into modes */ + + for(i = 0; i < 4; i++, base += 18) { + + /* Is this a detailed timing block or a monitor descriptor? */ + if(buffer[base] || buffer[base+1] || buffer[base+2]) { + + xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4); + yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4); + + SiS_Pr->CP_HDisplay[i] = xres; + SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2)); + SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4)); + SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8)); + SiS_Pr->CP_HBlankStart[i] = xres + 1; + SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i]; + + SiS_Pr->CP_VDisplay[i] = yres; + SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2)); + SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4)); + SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8)); + SiS_Pr->CP_VBlankStart[i] = yres + 1; + SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i]; + + SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10; + + SiS_Pr->CP_DataValid[i] = TRUE; + + /* Sort out invalid timings, interlace and too high clocks */ + if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) || + (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) || + (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) || + (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) || + (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) || + (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) || + (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_Clock[i] > 108000) || + (buffer[base+17] & 0x80)) { + + SiS_Pr->CP_DataValid[i] = FALSE; + + } else { + + paneltype = Panel_Custom; + + SiS_Pr->CP_HaveCustomData = TRUE; + + if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres; + if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres; + if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i]; + + SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8); + SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8); + + /* We must assume the panel can scale, since we have + * no scaling data + */ + checkexpand = FALSE; + cr37 |= 0x10; + + /* Extract the sync polarisation information. This only works + * if the Flags indicate a digital separate output. + */ + if((buffer[base+17] & 0x18) == 0x18) { + SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE; + SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE; + SiS_Pr->CP_SyncValid[i] = TRUE; + if(!havesync) { + cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20); + havesync = TRUE; + } + } else { + SiS_Pr->CP_SyncValid[i] = FALSE; + } + } + } + } + if(!havesync) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, + "CRT2: Unable to retrieve Sync polarity information\n"); + } + } + + if(paneltype && checkexpand) { + /* If any of the Established low-res modes is supported, the + * panel can scale automatically. For 800x600 panels, we only + * check the even lower ones. + */ + if(paneltype == Panel_800x600) { + if(buffer[0x23] & 0xfc) cr37 |= 0x10; + } else { + if(buffer[0x23]) cr37 |= 0x10; + } + } + + break; + + case 3: /* Analyze EDID V2 */ + case 4: + index = 0; + if((buffer[0x41] & 0x0f) == 0x03) { + index = 0x42 + 3; + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "CRT2: Display supports TMDS input on primary interface\n"); + } else if((buffer[0x41] & 0xf0) == 0x30) { + index = 0x46 + 3; + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "CRT2: Display supports TMDS input on secondary interface\n"); + } else { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "CRT2: Display does not support TMDS video interface (0x%02x)\n", + buffer[0x41]); + return 0; + } + + paneltype = Panel_Custom; + SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8); + SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8); + switch(xres) { + case 800: + if(yres == 600) { + paneltype = Panel_800x600; + checkexpand = TRUE; + } + break; + case 1024: + if(yres == 768) { + paneltype = Panel_1024x768; + checkexpand = TRUE; + } + break; + case 1152: + if(yres == 768) { + if(pSiS->VGAEngine == SIS_300_VGA) { + paneltype = Panel300_1152x768; + } else { + paneltype = Panel310_1152x768; + } + checkexpand = TRUE; + } + break; + case 1280: + if(yres == 960) { + if(pSiS->VGAEngine == SIS_315_VGA) { + paneltype = Panel310_1280x960; + } else { + paneltype = Panel300_1280x960; + } + } else if(yres == 1024) { + paneltype = Panel_1280x1024; + checkexpand = TRUE; + } else if(yres == 768) { + paneltype = Panel_1280x768; + checkexpand = FALSE; + cr37 |= 0x10; + } + break; + case 1400: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(yres == 1050) { + paneltype = Panel310_1400x1050; + checkexpand = TRUE; + } + } + break; +#if 0 /* Treat this one as custom since we have no timing data yet */ + case 1600: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(yres == 1200) { + paneltype = Panel310_1600x1200; + checkexpand = TRUE; + } + } + break; +#endif + } + + /* Determine if RGB18 or RGB24 */ + if(index) { + if((buffer[index] == 0x20) || (buffer[index] == 0x34)) { + cr37 |= 0x01; + } + } + + if(checkexpand) { + /* TODO - for now, we let the panel scale */ + cr37 |= 0x10; + } + + /* Now seek 4-Byte Timing codes and extract sync pol info */ + index = 0x80; + if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */ + lumsize = buffer[0x80] & 0x1f; + if(buffer[0x80] & 0x80) lumsize *= 3; + lumsize++; + index += lumsize; + } + index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */ + index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */ + numcodes = (buffer[0x7f] & 0xf8) >> 3; + if(numcodes) { + myindex = index; + seekcode = (xres - 256) / 16; + for(i=0; i<numcodes; i++) { + if(buffer[myindex] == seekcode) break; + myindex += 4; + } + if(buffer[myindex] == seekcode) { + cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20); + } else { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, + "CRT2: Unable to retrieve Sync polarity information\n"); + } + } else { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, + "CRT2: Unable to retrieve Sync polarity information\n"); + } + + /* Now seek the detailed timing descriptions for custom panels */ + if(paneltype == Panel_Custom) { + index += (numcodes * 4); + numcodes = buffer[0x7f] & 0x07; + for(i=0; i<numcodes; i++) { + xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4); + yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4); + + SiS_Pr->CP_HDisplay[i] = xres; + SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2)); + SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4)); + SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8)); + SiS_Pr->CP_HBlankStart[i] = xres + 1; + SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i]; + + SiS_Pr->CP_VDisplay[i] = yres; + SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2)); + SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4)); + SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8)); + SiS_Pr->CP_VBlankStart[i] = yres + 1; + SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i]; + + SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10; + + SiS_Pr->CP_DataValid[i] = TRUE; + + if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) || + (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) || + (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) || + (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) || + (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) || + (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) || + (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_Clock[i] > 108000) || + (buffer[index + 17] & 0x80)) { + + SiS_Pr->CP_DataValid[i] = FALSE; + + } else { + + SiS_Pr->CP_HaveCustomData = TRUE; + + if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i]; + + SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE; + SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE; + SiS_Pr->CP_SyncValid[i] = TRUE; + + SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8); + SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8); + + /* We must assume the panel can scale, since we have + * no scaling data + */ + cr37 |= 0x10; + + } + } + + } + + break; + + } + + /* 1280x960 panels are always RGB24, unable to scale and use + * high active sync polarity + */ + if(pSiS->VGAEngine == SIS_315_VGA) { + if(paneltype == Panel310_1280x960) cr37 &= 0x0e; + } else { + if(paneltype == Panel300_1280x960) cr37 &= 0x0e; + } + + for(i = 0; i < 7; i++) { + if(SiS_Pr->CP_DataValid[i]) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "Non-standard LCD timing data no. %d:\n", i); + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n", + SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i], + SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]); + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n", + SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i], + SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]); + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000); + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, + " To use this, add \"%dx%d\" to the list of Modes in the Display section\n", + SiS_Pr->CP_HDisplay[i], + SiS_Pr->CP_VDisplay[i]); + } + } + + if(paneltype) { + if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX; + if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY; + cr37 &= 0xf1; + cr37 |= 0x02; /* SiS301 */ + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,cr37); + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08); +#ifdef TWDEBUG + xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, + "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37); +#endif + } + return 0; +} + +USHORT +SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS) +{ + USHORT DDCdatatype,flag; + BOOLEAN foundcrt = FALSE; + int retry; + unsigned char buffer[256]; + + if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0; +/* if(pSiS->VBFlags & VB_30xBDH) return 0; */ + + if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0; + + SiS_Pr->SiS_DDC_SecAddr = 0x00; + + /* Probe supported DA's */ + flag = SiS_ProbeDDC(SiS_Pr); + if(flag & 0x10) { + SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */ + DDCdatatype = 4; + } else if(flag & 0x08) { + SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */ + DDCdatatype = 3; + } else if(flag & 0x02) { + SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */ + DDCdatatype = 1; + } else { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, + "Do DDC answer\n"); + return 0; /* no DDC support (or no device attached) */ + } + + /* Read the entire EDID */ + retry = 2; + do { + if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, + "CRT2: DDC read failed (attempt %d), %s\n", + (3-retry), (retry == 1) ? "giving up" : "retrying"); + retry--; + if(retry == 0) return 0xFFFF; + } else break; + } while(1); + + /* Analyze EDID. We don't have many chances to + * distinguish a flat panel from a CRT... + */ + switch(DDCdatatype) { + case 1: + if(buffer[0x14] & 0x80) { /* Display uses digital input */ + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "CRT2: Attached display expects digital input\n"); + return 0; + } + SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8); + SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8); + foundcrt = TRUE; + break; + case 3: + case 4: + if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */ + ((buffer[0x41] & 0x0f) != 0x02) && + ((buffer[0x41] & 0xf0) != 0x10) && + ((buffer[0x41] & 0xf0) != 0x20) ) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "CRT2: Attached display does not support analog input (0x%02x)\n", + buffer[0x41]); + return 0; + } + SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8); + SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8); + foundcrt = TRUE; + break; + } + + if(foundcrt) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10); + } + return(0); +} + +/* Generic I2C functions (compliant to i2c library) */ + +#if 0 +USHORT +SiS_I2C_GetByte(SiS_Private *SiS_Pr) +{ + return(SiS_ReadDDC2Data(SiS_Pr,0)); +} + +Bool +SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data) +{ + if(SiS_WriteDDC2Data(SiS_Pr,data)) return FALSE; + return TRUE; +} + +Bool +SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr) +{ + if(SiS_SetStart(SiS_Pr)) return FALSE; + if(SiS_WriteDDC2Data(SiS_Pr,addr)) return FALSE; + return TRUE; +} + +void +SiS_I2C_Stop(SiS_Private *SiS_Pr) +{ + SiS_SetStop(SiS_Pr); +} +#endif + +#endif + +void +SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh) +{ + USHORT tempbl; + + tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF)); + tempbl = (((tempbl & tempbh) << 8) | tempax); + SiS_SetCH70xx(SiS_Pr,tempbl); +} + +/* Generic I2C functions for Chrontel --------- */ + +void +SiS_SetSwitchDDC2(SiS_Private *SiS_Pr) +{ + SiS_SetSCLKHigh(SiS_Pr); + /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */ + SiS_WaitRetraceDDC(SiS_Pr); + + SiS_SetSCLKLow(SiS_Pr); + /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */ + SiS_WaitRetraceDDC(SiS_Pr); +} + +/* Set I2C start condition */ +/* This is done by a SD high-to-low transition while SC is high */ +USHORT +SiS_SetStart(SiS_Private *SiS_Pr) +{ + if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* SD->high */ + if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,0x00); /* SD->low = start condition */ + if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */ + return 0; +} + +/* Set I2C stop condition */ +/* This is done by a SD low-to-high transition while SC is high */ +USHORT +SiS_SetStop(SiS_Private *SiS_Pr) +{ + if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,0x00); /* SD->low */ + if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */ + if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */ + return 0; +} + +/* Write 8 bits of data */ +USHORT +SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax) +{ + USHORT i,flag,temp; + + flag=0x80; + for(i=0;i<8;i++) { + SiS_SetSCLKLow(SiS_Pr); /* SC->low */ + if(tempax & flag) { + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */ + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,0x00); /* Write bit (0) to SD */ + } + SiS_SetSCLKHigh(SiS_Pr); /* SC->high */ + flag >>= 1; + } + temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */ + return(temp); +} + +USHORT +SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax) +{ + USHORT i,temp,getdata; + + getdata=0; + for(i=0; i<8; i++) { + getdata <<= 1; + SiS_SetSCLKLow(SiS_Pr); + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); + SiS_SetSCLKHigh(SiS_Pr); + temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); + if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01; + } + return(getdata); +} + +USHORT +SiS_SetSCLKLow(SiS_Private *SiS_Pr) +{ + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Clk,0x00); /* SetSCLKLow() */ + SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); + return 0; +} + +USHORT +SiS_SetSCLKHigh(SiS_Private *SiS_Pr) +{ + USHORT temp,watchdog=1000; + + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Clk,SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */ + do { + temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); + } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); + if (!watchdog) { +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n"); +#endif + return 0xFFFF; + } + SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); + return 0; +} + +void +SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime) +{ + USHORT i; + + for(i=0; i<delaytime; i++) { + SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05); + } +} + +/* Check I2C acknowledge */ +/* Returns 0 if ack ok, non-0 if ack not ok */ +USHORT +SiS_CheckACK(SiS_Private *SiS_Pr) +{ + USHORT tempah; + + SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */ + SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index, + ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* (SD->high) */ + SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */ + tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* Read SD */ + SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */ + if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */ + else return(0); +} + +/* End of I2C functions ----------------------- */ + + +/* =============== SiS 315/330 O.E.M. ================= */ + +#ifdef SIS315H + +static USHORT +GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr) +{ + USHORT romptr; + + if(HwDeviceExtension->jChipType < SIS_330) { + romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS301B302B) + romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8); + } else { + romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS301B302B) + romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8); + } + return(romptr); +} + +static USHORT +GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr) +{ + USHORT romptr; + + if(HwDeviceExtension->jChipType < SIS_330) { + romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) + romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8); + } else { + romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) + romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8); + } + return(romptr); +} + +static USHORT +GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr) +{ + USHORT romptr; + + if(HwDeviceExtension->jChipType < SIS_330) { + romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) + romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8); + } else { + romptr = ROMAddr[0x194] | (ROMAddr[0x195] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) + romptr = ROMAddr[0x19a] | (ROMAddr[0x19b] << 8); + } + return(romptr); +} + +static USHORT +GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr) +{ + USHORT index; + + if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { + if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) { + if((index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) { + index >>= 4; + index *= 3; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; + else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; + return index; + } + } + } + + index = SiS_Pr->SiS_LCDResInfo & 0x0F; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) index -= 5; + else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6; + index--; + index *= 3; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; + else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; + return index; +} + +static USHORT +GetLCDPtrIndex(SiS_Private *SiS_Pr) +{ + USHORT index; + + index = SiS_Pr->SiS_LCDResInfo & 0x0F; + index--; + index *= 3; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; + else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; + + return index; +} + +/* +--------------------------------------------------------- + GetTVPtrIndex() + return 0 : NTSC Enhanced/Standard + 1 : NTSC Standard TVSimuMode + 2 : PAL Enhanced/Standard + 3 : PAL Standard TVSimuMode + 4 : HiVision Enhanced/Standard + 5 : HiVision Standard TVSimuMode +--------------------------------------------------------- +*/ +static USHORT +GetTVPtrIndex(SiS_Private *SiS_Pr) +{ + USHORT index; + + index = 0; + if(SiS_Pr->SiS_VBInfo & SetPALTV) index++; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index++; /* Hivision TV use PAL */ + + index <<= 1; + + if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (SiS_Pr->SiS_SetFlag & TVSimuMode)) + index++; + + return index; +} + +static void +SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr, USHORT ModeNo) +{ + USHORT delay=0,index,myindex,temp,romptr=0; + BOOLEAN dochiptest = TRUE; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* VGA */ + + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + romptr = GetRAMDACromptr(SiS_Pr, HwDeviceExtension, ROMAddr); + if(!romptr) return; + delay = ROMAddr[romptr]; + } else { + delay = 0x04; + if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { + if(IS_SIS650) { + delay = 0x0a; + } else if(IS_SIS740) { + delay = 0x00; + } else if(HwDeviceExtension->jChipType < SIS_330) { + delay = 0x0c; + } else { + delay = 0x0c; + } + } + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) + delay = 0x00; + } + + } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */ + + BOOLEAN gotitfrompci = FALSE; + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return; + + /* This is a piece of typical SiS crap: They code the OEM LCD + * delay into the code, at none defined place in the BIOS. + * We now have to start doing a PCI subsystem check here. + */ + + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { + gotitfrompci = TRUE; + dochiptest = FALSE; + delay = 0x03; + } + } + + if(!gotitfrompci) { + + index = GetLCDPtrIndexBIOS(SiS_Pr, HwDeviceExtension, BaseAddr); + myindex = GetLCDPtrIndex(SiS_Pr); + + if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { /* 650+30xLV */ + if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { +#if 0 /* Always use the second pointer on 650; some BIOSes */ + /* still carry old 301 data at the first location */ + romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS302LV) +#endif + romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8); + if(!romptr) return; + delay = ROMAddr[(romptr + index)]; + } else { + delay = SiS310_LCDDelayCompensation_650301B[myindex]; +#if 0 + if(SiS_Pr->SiS_VBType & VB_SIS302LV) + delay = SiS310_LCDDelayCompensation_650301B[myindex]; +#endif + } + } else { + delay = SiS310_LCDDelayCompensation_651301LV[myindex]; + if(SiS_Pr->SiS_VBType & VB_SIS302LV) + delay = SiS310_LCDDelayCompensation_651302LV[myindex]; + } + } else { + if((ROMAddr) && SiS_Pr->SiS_UseROM && /* 315, 330, 740, 650+301B */ + (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) { + romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr); + if(!romptr) return; + delay = ROMAddr[(romptr + index)]; + } else { + delay = SiS310_LCDDelayCompensation_301[myindex]; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { +#if 0 /* This data is (like the one in the BIOS) wrong. */ + if(IS_SIS550650740660) { + delay = SiS310_LCDDelayCompensation_650301B[myindex]; + } else { +#endif + delay = SiS310_LCDDelayCompensation_3xx301B[myindex]; +#if 0 + } +#endif + } + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(IS_SIS650) { + delay = SiS310_LCDDelayCompensation_LVDS650[myindex]; + } else { + delay = SiS310_LCDDelayCompensation_LVDS740[myindex]; + } + } + } + } + } + + } else { /* TV */ + + index = GetTVPtrIndex(SiS_Pr); + + if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { + if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { +#if 0 /* Always use the second pointer on 650; some BIOSes */ + /* still carry old 301 data at the first location */ + romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8); + if(SiS_Pr->SiS_VBType & VB_SIS302LV) +#endif + romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8); + if(!romptr) return; + delay = ROMAddr[romptr + index]; + } else { + delay = SiS310_TVDelayCompensation_301B[index]; +#if 0 + if(SiS_Pr->SiS_VBType & VB_SIS302LV) + delay = SiS310_TVDelayCompensation_301B[index]; +#endif + } + } else { + delay = SiS310_TVDelayCompensation_651301LV[index]; + if(SiS_Pr->SiS_VBType & VB_SIS302LV) + delay = SiS310_TVDelayCompensation_651302LV[index]; + } + } else { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + romptr = GetTVromptr(SiS_Pr, HwDeviceExtension, ROMAddr); + if(!romptr) return; + delay = ROMAddr[romptr + index]; + } else { + delay = SiS310_TVDelayCompensation_301[index]; + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(IS_SIS740) + delay = SiS310_TVDelayCompensation_740301B[index]; + else + delay = SiS310_TVDelayCompensation_301B[index]; + } + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) + delay = SiS310_TVDelayCompensation_LVDS[index]; + } + } + + } + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); + } else { + if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) { + delay <<= 4; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay); + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); + } + } + } else { + if(dochiptest && IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { + temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4; + if(temp == 8) { /* 1400x1050 BIOS */ + delay &= 0x0f; + delay |= 0xb0; + } else if(temp == 6) { + delay &= 0x0f; + delay |= 0xc0; + } else if(temp > 7) { /* 1280x1024 BIOS */ + delay = 0x35; + } + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay); + } else { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); + } + } +} + +static void +SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index,temp,romptr=0; + + temp = GetTVPtrIndex(SiS_Pr); + temp >>= 1; /* 0: NTSC, 1: PAL, 2: HiTV */ + + if(ModeNo<=0x13) + index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; + else + index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; + + if(ROMAddr && SiS_Pr->SiS_UseROM) { + romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8); + if(HwDeviceExtension->jChipType >= SIS_330) { + romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8); + } + } + + if(romptr) { + temp <<= 1; + temp = ROMAddr[romptr + temp + index]; + } else { + temp = SiS310_TVAntiFlick1[temp][index]; + } + temp <<= 4; + + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */ +} + +static void +SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index,temp,romptr=0; + + temp = GetTVPtrIndex(SiS_Pr); + temp >>= 1; /* 0: NTSC, 1: PAL, 2: HiTV */ + + if(ModeNo<=0x13) + index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; + else + index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; + + if(ROMAddr && SiS_Pr->SiS_UseROM) { + romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8); + if(HwDeviceExtension->jChipType >= SIS_330) { + romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8); + } + } + + if(romptr) { + temp <<= 1; + temp = ROMAddr[romptr + temp + index]; + } else { + temp = SiS310_TVEdge1[temp][index]; + } + temp <<= 5; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */ +} + +static void +SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index, temp, i, j; + UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect; + + temp = GetTVPtrIndex(SiS_Pr); + temp >>= 1; /* 0: NTSC, 1: PAL, 2: HiTV */ + + if (ModeNo<=0x13) { + index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex; + } else { + index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) temp = 1; /* Hivision TV uses PAL */ + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); + } + for(i=0x48; i<=0x4A; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); + } + } else { + for(i=0x35, j=0; i<=0x38; i++, j++){ + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]); + } + } + + if(ROMAddr && SiS_Pr->SiS_UseROM) { + OutputSelect = ROMAddr[0xf3]; + if(HwDeviceExtension->jChipType >= SIS_330) { + OutputSelect = ROMAddr[0x11b]; + } + } + if(OutputSelect & EnablePALMN) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + temp &= (EnablePALM | EnablePALN); + if(temp == EnablePALM) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]); + } + for(i=0x48; i<=0x4A; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]); + } + } else { + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter[index][j]); + } + } + } + /* PALN : Is this data correct? */ + if(temp == EnablePALN) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]); + } + for(i=0x48, j=0; i<=0x4A; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]); + } + } else { + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter[index][j]); + } + } + } + } + } +} + +static void +SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index,temp,temp1,i,j,resinfo,romptr=0; + + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; + + temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); /* if PALM/N not set */ + temp1 &= (EnablePALM | EnablePALN); + if(temp1) return; + + if(ModeNo<=0x13) { + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + + temp = GetTVPtrIndex(SiS_Pr); + /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics, + * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text + */ + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8); + if(HwDeviceExtension->jChipType >= SIS_330) { + romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8); + } + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8); + if(HwDeviceExtension->jChipType >= SIS_330) { + romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8); + } + if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) { + romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8); + if(HwDeviceExtension->jChipType >= SIS_330) { + romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8); + } + } + } + } + if(romptr) { + romptr += (temp << 2); + for(j=0, i=0x31; i<=0x34; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); + } + } else { + index = temp % 2; + temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */ + for(j=0, i=0x31; i<=0x34; i++, j++) { + if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); + else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_SetFlag & TVSimuMode)) + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]); + else + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); + } + } + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */ + if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) { + if(resinfo == SIS_RI_640x480) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f); + } else if (resinfo == SIS_RI_800x600) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f); + } else if (resinfo == SIS_RI_1024x768) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7b); + } + } + } +} + +void +SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo); + + if(SiS_Pr->UseCustomMode) return; + + if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) { + SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex); + SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex); + SetYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex); + if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) { + SetEdgeEnhance(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex); + } + } +} + +/* FinalizeLCD + * This finalizes some CRT2 registers for the very panel used. + * If we have a backup if these registers, we use it; otherwise + * we set the register according to most BIOSes. However, this + * function looks quite different in every BIOS, so you better + * pray that we have a backup... + */ +void +SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp; + USHORT resinfo,modeflag; + + if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return; + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return; + if(SiS_Pr->UseCustomMode) return; + + if(SiS_Pr->SiS_CustomT == CUT_COMPAQ12802) return; + + if(ModeNo <= 0x13) { + resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + + if(IS_SIS650) { + if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) { + if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02); + } else { + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); + } + } + } + + if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { /* Maybe all panels? */ + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); + return; + } + } + + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) { /* Maybe all panels? */ + /* Maybe ACER only? */ + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); + } + tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36); + tempch &= 0xf0; + tempch >>= 4; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + if(tempch == 0x03) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x25); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x1b); + } + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76); + } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d); + } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* From 1.10.8w */ + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90); + if(ModeNo <= 0x13) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x11); + if((resinfo == 0) || (resinfo == 2)) return; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x18); + if((resinfo == 1) || (resinfo == 3)) return; + } + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02); + if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */ +#if 0 + tempbx = 806; /* 0x326 */ /* other older BIOSes */ + tempbx--; + temp = tempbx & 0xff; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,temp); + temp = (tempbx >> 8) & 0x03; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp); +#endif + } + } else { + if(ModeNo <= 0x13) { + if(ModeNo <= 1) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x70); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xff); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12); + } + if(!(modeflag & HalfDCLK)) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x20); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,0x1a); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,0x28); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x4c); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc); + if(ModeNo == 0x12) { + switch(tempch) { + case 0: + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1a,0x10); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x48); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12); + break; + case 2: + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48); + break; + case 3: + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95); + break; + } + } + } + } + } + } + } else { + tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01); + tempcl &= 0x0f; + tempbh &= 0x70; + tempbh >>= 4; + tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04); + tempbx = (tempbh << 8) | tempbl; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) { + if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { + tempbx = 770; + } else { + if(tempbx > 770) tempbx = 770; + if(SiS_Pr->SiS_VGAVDE < 600) { + tempax = 768 - SiS_Pr->SiS_VGAVDE; + tempax >>= 4; /* From 1.10.7w; 1.10.6s: 3; */ + if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* From 1.10.7w; 1.10.6s: < 480; >>=1; */ + tempbx -= tempax; + } + } + } else return; + } +#if 0 + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + } +#endif + temp = tempbx & 0xff; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp); + temp = (tempbx & 0xff00) >> 8; + temp <<= 4; + temp |= tempcl; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp); + } + } +} + +#endif + + +/* ================= SiS 300 O.E.M. ================== */ + +#ifdef SIS300 + +void +SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex) +{ + USHORT crt2crtc=0, modeflag, myindex=0; + UCHAR temp; + int i; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC; + } + + crt2crtc &= 0x3f; + + if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf); + } + + if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { + if(modeflag & HalfDCLK) myindex = 1; + + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + for(i=0; i<7; i++) { + if(barco_p1[myindex][crt2crtc][i][0]) { + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, + barco_p1[myindex][crt2crtc][i][0], + barco_p1[myindex][crt2crtc][i][2], + barco_p1[myindex][crt2crtc][i][1]); + } + } + } + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00); + if(temp & 0x80) { + temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18); + temp++; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp); + } + } +} + +#if 0 /* Not used */ +static USHORT +GetRevisionID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + ULONG temp1; +#ifndef LINUX_XF86 + ULONG base; +#endif + USHORT temp2 = 0; + + if((HwDeviceExtension->jChipType==SIS_540)|| + (HwDeviceExtension->jChipType==SIS_630)|| + (HwDeviceExtension->jChipType==SIS_730)) { +#ifndef LINUX_XF86 + base = 0x80000008; + OutPortLong(base,0xcf8); + temp1 = InPortLong(0xcfc); +#else + temp1=pciReadLong(0x00000000, 0x08); +#endif + temp1 &= 0x000000FF; + temp2 = (USHORT)(temp1); + return temp2; + } + return 0; +} +#endif + +static USHORT +GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr, int Flag) +{ + USHORT tempbx=0,romptr=0; + UCHAR customtable300[] = { + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff + }; + UCHAR customtable630[] = { + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff + }; + + if(HwDeviceExtension->jChipType == SIS_300) { + + tempbx = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2; + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4; + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3; + } + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(ROMAddr[0x235] & 0x80) { + tempbx = SiS_Pr->SiS_LCDTypeInfo; + if(Flag) { + romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8); + if(romptr) { + tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; + } else { + tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo]; + } + if(tempbx == 0xFF) return 0xFFFF; + } + tempbx <<= 1; + if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; + } + } + + } else { + + if(Flag) { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8); + if(romptr) { + tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; + } else { + tempbx = 0xff; + } + } else { + tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo]; + } + if(tempbx == 0xFF) return 0xFFFF; + tempbx <<= 2; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + return tempbx; + } + tempbx = SiS_Pr->SiS_LCDTypeInfo << 2; + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; + if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; + } + return tempbx; +} + +static void +SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index,temp,romptr=0; + + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return; + + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(!(ROMAddr[0x237] & 0x01)) return; + if(!(ROMAddr[0x237] & 0x02)) return; + romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8); + } + + /* The Panel Compensation Delay should be set according to tables + * here. Unfortunately, various BIOS versions don't case about + * a uniform way using eg. ROM byte 0x220, but use different + * hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). + * Thus we don't set this if the user select a custom pdc or if + * we otherwise detected a valid pdc. + */ + if(HwDeviceExtension->pdc) return; + + temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0); + + if(SiS_Pr->UseCustomMode) + index = 0; + else + index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex; + + if(HwDeviceExtension->jChipType != SIS_300) { + if(romptr) { + romptr += (temp * 2); + romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8); + romptr += index; + temp = ROMAddr[romptr]; + } else { + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + temp = SiS300_OEMLCDDelay2[temp][index]; + } else { + temp = SiS300_OEMLCDDelay3[temp][index]; + } + } + } else { + if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) { + if(romptr) { + romptr += (temp * 2); + romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8); + romptr += index; + temp = ROMAddr[romptr]; + } else { + temp = SiS300_OEMLCDDelay5[temp][index]; + } + } else { + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8); + if(romptr) { + romptr += (temp * 2); + romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8); + romptr += index; + temp = ROMAddr[romptr]; + } else { + temp = SiS300_OEMLCDDelay4[temp][index]; + } + } else { + temp = SiS300_OEMLCDDelay4[temp][index]; + } + } + } + temp &= 0x3c; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */ +} + +static void +SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ +#if 0 /* Unfinished; Data table missing */ + USHORT index,temp; + + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(!(ROMAddr[0x237] & 0x01)) return; + if(!(ROMAddr[0x237] & 0x04)) return; + /* No rom pointer in BIOS header! */ + } + + temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 1); + if(temp = 0xFFFF) return; + + index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex; + for(i=0x14, j=0; i<=0x17; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]); + } + SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07)); + + index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex; + SiS_SetReg1(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]); + SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]); + SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38)); + for(i=0x1b, j=3; i<=0x1d; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]); + } +#endif +} + +static USHORT +GetOEMTVPtr(SiS_Private *SiS_Pr) +{ + USHORT index; + + index = 0; + if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4; + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2; + else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3; + else if(SiS_Pr->SiS_VBInfo & SetPALTV) index += 1; + } else { + if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) index += 2; + if(SiS_Pr->SiS_VBInfo & SetPALTV) index += 1; + } + return index; +} + +static void +SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index,temp,romptr=0; + + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(!(ROMAddr[0x238] & 0x01)) return; + if(!(ROMAddr[0x238] & 0x02)) return; + romptr = ROMAddr[0x241] | (ROMAddr[0x242] << 8); + } + + temp = GetOEMTVPtr(SiS_Pr); + + index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex; + + if(romptr) { + romptr += (temp * 2); + romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8); + romptr += index; + temp = ROMAddr[romptr]; + } else { + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + temp = SiS300_OEMTVDelay301[temp][index]; + } else { + temp = SiS300_OEMTVDelayLVDS[temp][index]; + } + } + temp &= 0x3c; + SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */ +} + +static void +SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex) +{ + USHORT index,temp,romptr=0; + + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(!(ROMAddr[0x238] & 0x01)) return; + if(!(ROMAddr[0x238] & 0x04)) return; + romptr = ROMAddr[0x243] | (ROMAddr[0x244] << 8); + } + + temp = GetOEMTVPtr(SiS_Pr); + + index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex; + + if(romptr) { + romptr += (temp * 2); + romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8); + romptr += index; + temp = ROMAddr[romptr]; + } else { + temp = SiS300_OEMTVFlicker[temp][index]; + } + temp &= 0x70; + SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp); /* index 0A D[6:4] */ +} + +static void +SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index,i,j,temp,romptr=0; + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) return; + + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(!(ROMAddr[0x238] & 0x01)) return; + if(!(ROMAddr[0x238] & 0x08)) return; + romptr = ROMAddr[0x245] | (ROMAddr[0x246] << 8); + } + + temp = GetOEMTVPtr(SiS_Pr); + + index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex; + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + for(i=0x31, j=0; i<=0x34; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]); + } + } else { + if(romptr) { + romptr += (temp * 2); + romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8); + romptr += (index * 4); + for(i=0x31, j=0; i<=0x34; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); + } + } else { + for(i=0x31, j=0; i<=0x34; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]); + } + } + } +} + +static void +SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT index,temp,temp1,i,j,romptr=0; + + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return; + + if((ROMAddr) && SiS_Pr->SiS_UseROM) { + if(!(ROMAddr[0x238] & 0x01)) return; + if(!(ROMAddr[0x238] & 0x10)) return; + romptr = ROMAddr[0x247] | (ROMAddr[0x248] << 8); + } + + temp = GetOEMTVPtr(SiS_Pr); + + index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex; + + if(HwDeviceExtension->jChipType > SIS_300) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) { + temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35); + if(temp1 & (EnablePALM | EnablePALN)) { + temp = 8; + if(!(temp1 & EnablePALM)) temp = 9; + } + } + } + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); + } + for(i=0x48; i<=0x4A; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); + } + } else { + if(romptr) { + romptr += (temp * 2); + romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8); + romptr += (index * 4); + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); + } + } else { + for(i=0x35, j=0; i<=0x38; i++, j++) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]); + } + } + } +} + +void +SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefTableIndex) +{ + USHORT OEMModeIdIndex=0; + + if(!SiS_Pr->UseCustomMode) { + OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo); + if(!(OEMModeIdIndex)) return; + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex); + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex); + } + } + if(SiS_Pr->UseCustomMode) return; + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex); + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex); + SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex); + SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex); + } + } +} +#endif + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h new file mode 100644 index 000000000..55fe52ff2 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h @@ -0,0 +1,373 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h,v 1.17 2003/07/28 12:39:46 twini Exp $ */ +/* + * Data and prototypes for init301.c + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * Based on code by Silicon Intergrated Systems + * + */ + +#ifndef _INIT301_ +#define _INIT301_ + +#include "osdef.h" + +#include "initdef.h" +#include "vgatypes.h" +#include "vstruct.h" + +#ifdef LINUX_XF86 +#include "xf86.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "sis.h" +#include "sis_regs.h" +#endif + +#ifdef LINUX_KERNEL +#ifdef SIS_CP +#undef SIS_CP +#endif +#include <linux/config.h> +#include <linux/version.h> +#include <asm/io.h> +#include <linux/types.h> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#include <linux/sisfb.h> +#else +#include <video/sisfb.h> +#endif +#endif + +const UCHAR SiS_HiVisionTable[3][64] = { + { + 0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c, + 0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a, + 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b, + 0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17, + 0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02, + 0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40, + 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53, + 0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00 + }, + { + 0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c, + 0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a, + 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, + 0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03, + 0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96, + 0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40, + 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3, + 0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 + }, + { + 0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, + 0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, + 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, + 0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13, + 0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, + 0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40, + 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a, + 0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 + } +}; + +const UCHAR SiS_HiTVGroup3_1[] = { + 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13, + 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6, + 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20, + 0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10, + 0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80, + 0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0, + 0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e, + 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01 +}; + +const UCHAR SiS_HiTVGroup3_2[] = { + 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a, + 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6, + 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20, + 0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10, + 0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80, + 0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94, + 0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64, + 0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01 +}; + +extern BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *); + +BOOLEAN SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr); +BOOLEAN SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr); +BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr); +USHORT SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +BOOLEAN SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT MODEIdIndex, + USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo); +void SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +#ifdef SIS315H +void SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex); +#endif +void SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); +void SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO ); +void SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +USHORT SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); +USHORT SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +USHORT SiS_CalcDelayVB(SiS_Private *SiS_Pr); +USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR); +void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR); +void SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND); +USHORT SiS_GetVGAHT2(SiS_Private *SiS_Pr); +void SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeIdIndex, USHORT RefreshRateTableIndex, + USHORT BaseAddr, USHORT ModeNo); +void SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex); +void SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_EnableCRT2(SiS_Private *SiS_Pr); +void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension, int checkcrt2mode); +BOOLEAN SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO); +BOOLEAN SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO); +BOOLEAN SiS_BridgeInSlave(SiS_Private *SiS_Pr); +void SiS_SetTVSystem(SiS_Private *SiS_Pr); +void SiS_LongWait(SiS_Private *SiS_Pr); +USHORT SiS_GetQueueConfig(SiS_Private *SiS_Pr); +void SiS_VBLongWait(SiS_Private *SiS_Pr); +USHORT SiS_GetVCLKLen(SiS_Private *SiS_Pr, UCHAR *ROMAddr); +void SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_WaitRetraceDDC(SiS_Private *SiS_Pr); +void SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +#ifdef SIS315H +void SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex); +#endif +void SiS_SetTPData(SiS_Private *SiS_Pr); +void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo); +void SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex); +void SiS_GetCHTVRegPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex); +void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax); +USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax); +void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax); +USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax); +void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax); +USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax); +#ifdef LINUX_XF86 +USHORT SiS_I2C_GetByte(SiS_Private *SiS_Pr); +Bool SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data); +Bool SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr); +void SiS_I2C_Stop(SiS_Private *SiS_Pr); +#endif +void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh); +void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr); +USHORT SiS_SetStart(SiS_Private *SiS_Pr); +USHORT SiS_SetStop(SiS_Private *SiS_Pr); +void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime); +USHORT SiS_SetSCLKLow(SiS_Private *SiS_Pr); +USHORT SiS_SetSCLKHigh(SiS_Private *SiS_Pr); +USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax); +USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax); +USHORT SiS_CheckACK(SiS_Private *SiS_Pr); + +#ifdef SIS315H +void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); +void SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex); +#endif +#ifdef SIS300 +void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex); +void SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr, + UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex); +#endif +BOOLEAN SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension); + +void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +/* void SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex); */ + +BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex); +void SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex); +#ifdef SIS315H +void SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex); +#endif +void SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex); +#ifdef SIS300 +void SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +#endif +#ifdef SIS315H +void SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr); +#endif +BOOLEAN SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +void SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +void SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR* ROMAddr,PSIS_HW_DEVICE_INFO,USHORT DelayTime); +void SiS_SetPanelDelayLoop(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT DelayTime, USHORT DelayLoop); +void SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay); +void SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay); +void SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay); +void SiS_VBWait(SiS_Private *SiS_Pr); + +void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); + +void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr); +#ifdef SIS315H +void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT BaseAddr); +void SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +void SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +void SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +void SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +void SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +void SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +#ifdef NEWCH701x +void SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr); +#endif +#endif /* 315 */ +#if 0 +BOOLEAN SiS_IsSomethingCR5F(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +#endif +BOOLEAN SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +BOOLEAN SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +BOOLEAN SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +BOOLEAN SiS_IsSR13_CR30(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); + +extern void SiS_SetReg1(USHORT, USHORT, USHORT); +extern void SiS_SetReg3(USHORT, USHORT); +extern UCHAR SiS_GetReg1(USHORT, USHORT); +extern UCHAR SiS_GetReg2(USHORT); +extern BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex); +extern BOOLEAN SiS_GetRatePtr(SiS_Private *SiS_Pr, ULONG, USHORT); +extern void SiS_SetReg4(USHORT, ULONG); +extern ULONG SiS_GetReg3(USHORT); +extern void SiS_SetReg5(USHORT, USHORT); +extern USHORT SiS_GetReg4(USHORT); +extern void SiS_DisplayOff(SiS_Private *SiS_Pr); +extern void SiS_DisplayOn(SiS_Private *SiS_Pr); +extern UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex); +extern BOOLEAN SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType); +extern BOOLEAN SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType); +extern void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex); +#ifdef SIS315H +extern UCHAR SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); +#endif + +/* DDC functions */ +USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine, + USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32); +USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr); +USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr); +USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr); +void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno); +USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr); +USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr); +USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer); +USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine, + USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer); +#ifdef LINUX_XF86 +USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS); +USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS); +#endif + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h new file mode 100644 index 000000000..285e4e4ba --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h @@ -0,0 +1,558 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.15 2003/06/26 22:35:17 twini Exp $ */ +/* + * Global definitions for init.c and init301.c + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * Based on code by Silicon Intergrated Systems + * + */ + +#ifndef _INITDEF_ +#define _INITDEF_ + +#define SiS300 0x0300 +#define SiS540 0x5300 +#define SiS630 0x6300 +#define SiS730 0x6300 + +/* SiS_VBType */ +#define VB_SIS301 0x0001 +#define VB_SIS301B 0x0002 +#define VB_SIS302B 0x0004 +#define VB_SIS301LV 0x0008 +#define VB_SIS302LV 0x0010 +#define VB_SIS30xLV VB_SIS301LV +#define VB_SIS30xNEW VB_SIS302LV +#define VB_NoLCD 0x8000 +#define VB_SIS301BLV302BLV (VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV) +#define VB_SIS301B302B (VB_SIS301B|VB_SIS302B) +#define VB_SIS301LV302LV (VB_SIS301LV|VB_SIS302LV) + +#define IS_SIS650 (HwDeviceExtension->jChipType == SIS_650) +#define IS_SIS740 (HwDeviceExtension->jChipType == SIS_740) +#define IS_SIS330 (HwDeviceExtension->jChipType == SIS_330) +#define IS_SIS550 (HwDeviceExtension->jChipType == SIS_550) +#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652)) +#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653)) +#define IS_SIS65x (IS_SIS651 || IS_SISM650) +#define IS_SIS660 (HwDeviceExtension->jChipType == SIS_660) +#define IS_SIS760 (HwDeviceExtension->jChipType == SIS_760) +#define IS_SIS650660 (IS_SIS650 || IS_SIS660) +#define IS_SIS650740 ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330)) +#define IS_SIS650740660 (IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760) +#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760) + +#define CRT1Len 17 +#define LVDSCRT1Len 15 +#define CHTVRegDataLen 5 + +/* SiS_ModeType */ +#define ModeText 0x00 +#define ModeCGA 0x01 +#define ModeEGA 0x02 +#define ModeVGA 0x03 +#define Mode15Bpp 0x04 +#define Mode16Bpp 0x05 +#define Mode24Bpp 0x06 +#define Mode32Bpp 0x07 + +#define ModeInfoFlag 0x07 +#define IsTextMode 0x07 + +#define DACInfoFlag 0x0018 +#define MemoryInfoFlag 0x01E0 +#define MemorySizeShift 5 + +/* modeflag */ +#define Charx8Dot 0x0200 +#define LineCompareOff 0x0400 +#define CRT2Mode 0x0800 +#define HalfDCLK 0x1000 +#define NoSupportSimuTV 0x2000 +#define DoubleScanMode 0x8000 + +/* Infoflag */ +#define SupportAllCRT2 0x0078 +#define SupportTV 0x0008 +#define SupportHiVisionTV 0x0010 +#define SupportLCD 0x0020 +#define SupportRAMDAC2 0x0040 +#define NoSupportTV 0x0070 +#define NoSupportHiVisionTV 0x0060 +#define NoSupportLCD 0x0058 +#define SupportCHTV 0x0800 +#define SupportTV1024 0x0800 +#define InterlaceMode 0x0080 +#define SupportHiVisionTV2 0x1000 +#define SyncPP 0x0000 +#define SyncPN 0x4000 +#define SyncNP 0x8000 +#define SyncNN 0xc000 +#define ECLKindex0 0x0000 +#define ECLKindex1 0x0100 +#define ECLKindex2 0x0200 +#define ECLKindex3 0x0300 +#define ECLKindex4 0x0400 + +/* VBInfo */ +#define SetSimuScanMode 0x0001 /* CR 30 */ +#define SwitchToCRT2 0x0002 +#define SetCRT2ToAVIDEO 0x0004 +#define SetCRT2ToSVIDEO 0x0008 +#define SetCRT2ToSCART 0x0010 +#define SetCRT2ToLCD 0x0020 +#define SetCRT2ToRAMDAC 0x0040 +#define SetCRT2ToHiVisionTV 0x0080 +#define SetCRT2ToTV 0x009C /* alias */ +#define SetNTSCTV 0x0000 /* CR 31 */ +#define SetPALTV 0x0100 +#define SetInSlaveMode 0x0200 +#define SetNotSimuMode 0x0400 +#define SetNotSimuTVMode 0x0400 +#define SetDispDevSwitch 0x0800 +#define LoadDACFlag 0x1000 +#define SetCHTVOverScan 0x1000 /* TW: Re-defined (from 0x8000) */ +#define DisableCRT2Display 0x2000 +#define CRT2DisplayFlag 0x2000 +#define DriverMode 0x4000 +#define HotKeySwitch 0x8000 /* TW: ? */ +#define SetCRT2ToLCDA 0x8000 + +/* SetFlag */ +#define ProgrammingCRT2 0x01 +#define TVSimuMode 0x02 +#define RPLLDIV2XO 0x04 +#define LCDVESATiming 0x08 +#define EnableLVDSDDA 0x10 +#define SetDispDevSwitchFlag 0x20 +#define CheckWinDos 0x40 +#define SetDOSMode 0x80 + +/* SysFlags */ +#define SF_Is651 0x0001 +#define SF_IsM650 0x0002 +#define SF_Is652 0x0004 +#define SF_IsM652 0x0008 +#define SF_IsM653 0x0010 +#define SF_Is660 0x8000 + +#define PanelRGB18Bit 0x0100 +#define PanelRGB24Bit 0x0000 + +#define TVOverScan 0x10 /* Bit in CR35 (300 series only) */ +#define TVOverScanShift 4 +#define ClearBufferFlag 0x20 + +/* CR32 (Newer 630, and 315 series) + + [0] VB connected with CVBS + [1] VB connected with SVHS + [2] VB connected with SCART + [3] VB connected with LCD + [4] VB connected with CRT2 (secondary VGA) + [5] CRT1 monitor is connected + [6] VB connected with Hi-Vision TV + [7] VB connected with DVI combo connector + + + CR37 + + [0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS) + [3:1] External chip + 300 series: + 001 SiS301 (never seen) + 010 LVDS + 011 LVDS + Tumpion Zurac + 100 LVDS + Chrontel 7005 + 110 Chrontel 7005 + 315 series + 001 SiS30x (never seen) + 010 LVDS + 011 LVDS + Chrontel 7019 + All other combinations reserved + [4] LVDS: 0: Panel Link expands / 1: Panel Link does not expand + 30x: 0: Bridge scales / 1: Bridge does not scale = Panel scales (if possible) + [5] LCD polarity select + 0: VESA DMT Standard + 1: EDID 2.x defined + [6] LCD horizontal polarity select + 0: High active + 1: Low active + [7] LCD vertical polarity select + 0: High active + 1: Low active +*/ + +/* CR37: LCDInfo */ +#define LCDRGB18Bit 0x0001 +#define LCDNonExpanding 0x0010 +#define DontExpandLCD LCDNonExpanding +#define LCDNonExpandingShift 4 +#define DontExpandLCDShift LCDNonExpandingShift +#define LCDSync 0x0020 +#define LCDPass11 0x0100 +#define LCDSyncBit 0x00e0 +#define LCDSyncShift 6 + +/* CR38 (315 series) */ +#define EnableDualEdge 0x01 +#define SetToLCDA 0x02 /* LCD channel A (302B/LV and 650+LVDS only) */ +#define EnableSiSHiVision 0x04 /* HiVision (HDTV) on SiS bridge */ +#define EnableLVDSScart 0x04 /* Scart on Ch7019 (unofficial definition - TW) */ +#define EnableLVDSHiVision 0x08 /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */ +#define EnableHiVision750 0x08 /* Enable 750P HiVision mode (30xLV only) */ +#define EnableHiVision525 0x10 /* Enable 525P HiVision mode (30xLV only) */ +#define SiSHiVision2 0x20 /* ? - | --- mask 0x38 combinations have different meaning! */ +#define EnablePALM 0x40 /* 1 = Set PALM */ +#define EnablePALN 0x80 /* 1 = Set PALN */ + +#define SetSCARTOutput 0x01 +#define BoardTVType 0x02 + +#define EnablePALMN 0x40 /* Romflag: 1 = Allow PALM/PALN */ + +/* CR39 (650) */ +#define LCDPass1_1 0x01 /* LVDS only; set by driver to pass 1:1 data to LVDS output */ +#define Enable302LV_DualLink 0x04 /* 30xNEW (302LV) only; set by mode switching function */ + + +/* CR79 (315 series only) + [3-0] Notify driver + 0001 Mode Switch event (set by BIOS) + 0010 Epansion On/Off event + 0011 TV UnderScan/OverScan event + 0100 Set Brightness event + 0101 Set Contrast event + 0110 Set Mute event + 0111 Set Volume Up/Down event + [4] Enable Backlight Control by BIOS/driver + (set by driver; set means that the BIOS should + not touch the backlight registers because eg. + the driver already switched off the backlight) + [5] PAL/NTSC (set by BIOS) + [6] Expansion On/Off (set by BIOS; copied to CR32[4]) + [7] TV UnderScan/OverScan (set by BIOS) +*/ + +/* LCDResInfo */ +#define Panel300_800x600 0x01 /* CR36 */ +#define Panel300_1024x768 0x02 +#define Panel300_1280x1024 0x03 +#define Panel300_1280x960 0x04 +#define Panel300_640x480 0x05 +#define Panel300_1024x600 0x06 +#define Panel300_1152x768 0x07 +#define Panel300_1280x768 0x0a +#define Panel300_320x480 0x0e /* fstn - TW: This is fake, can be any */ +#define Panel300_Custom 0x0f +#define Panel300_Barco1366 0x10 + +#define Panel310_800x600 0x01 +#define Panel310_1024x768 0x02 +#define Panel310_1280x1024 0x03 +#define Panel310_640x480 0x04 +#define Panel310_1024x600 0x05 +#define Panel310_1152x864 0x06 +#define Panel310_1280x960 0x07 +#define Panel310_1152x768 0x08 /* LVDS only */ +#define Panel310_1400x1050 0x09 +#define Panel310_1280x768 0x0a +#define Panel310_1600x1200 0x0b +#define Panel310_640x480_2 0x0c +#define Panel310_640x480_3 0x0d +#define Panel310_320x480 0x0e /* fstn - TW: This is fake, can be any */ +#define Panel310_Custom 0x0f + +#define Panel_800x600 0x01 /* Unified values */ +#define Panel_1024x768 0x02 +#define Panel_1280x1024 0x03 +#define Panel_640x480 0x04 +#define Panel_1024x600 0x05 +#define Panel_1152x864 0x06 +#define Panel_1280x960 0x07 +#define Panel_1152x768 0x08 /* LVDS only */ +#define Panel_1400x1050 0x09 +#define Panel_1280x768 0x0a /* LVDS only */ +#define Panel_1600x1200 0x0b +#define Panel_640x480_2 0x0c +#define Panel_640x480_3 0x0d +#define Panel_320x480 0x0e /* fstn - TW: This is fake, can be any */ +#define Panel_Custom 0x0f +#define Panel_Barco1366 0x10 +#define Panel_848x480 0x11 + +/* Index in ModeResInfo table */ +#define SIS_RI_320x200 0 +#define SIS_RI_320x240 1 +#define SIS_RI_320x400 2 +#define SIS_RI_400x300 3 +#define SIS_RI_512x384 4 +#define SIS_RI_640x400 5 +#define SIS_RI_640x480 6 +#define SIS_RI_800x600 7 +#define SIS_RI_1024x768 8 +#define SIS_RI_1280x1024 9 +#define SIS_RI_1600x1200 10 +#define SIS_RI_1920x1440 11 +#define SIS_RI_2048x1536 12 +#define SIS_RI_720x480 13 +#define SIS_RI_720x576 14 +#define SIS_RI_1280x960 15 +#define SIS_RI_800x480 16 +#define SIS_RI_1024x576 17 +#define SIS_RI_1280x720 18 +#define SIS_RI_856x480 19 +#define SIS_RI_1280x768 20 +#define SIS_RI_1400x1050 21 +#define SIS_RI_1152x864 22 +#define SIS_RI_848x480 23 +#define SIS_RI_1360x768 24 +#define SIS_RI_1024x600 25 +#define SIS_RI_1152x768 26 +#define SIS_RI_768x576 27 +#define SIS_RI_1360x1024 28 + +#define ExtChipType 0x0e +#define ExtChip301 0x02 +#define ExtChipLVDS 0x04 +#define ExtChipTrumpion 0x06 +#define ExtChipCH7005 0x08 +#define ExtChipMitacTV 0x0a /* TW: Incorrect, 0x0a = Chrontel 7005 only */ + +#define IsM650 0x80 /* TW: CR5F */ + +#define LCDDataLen 8 +#define HiTVDataLen 12 +#define TVDataLen 16 +#define SetPALTV 0x0100 +#define HalfDCLK 0x1000 /* modeflag */ + +#define NTSCHT 1716 +#define NTSC2HT 1920 +#define NTSCVT 525 +#define PALHT 1728 +#define PALVT 625 +#define StHiTVHT 892 +#define StHiTVVT 1126 +#define StHiTextTVHT 1000 +#define StHiTextTVVT 1126 +#define ExtHiTVHT 2100 +#define ExtHiTVVT 1125 + +#define VCLKStartFreq 25 +#define SoftDramType 0x80 + +/* Indices in (VB)VCLKData tables */ + +#define VCLK28 0x00 /* Index in VCLKData table (300 and 315) */ +#define VCLK40 0x04 /* Index in VCLKData table (300 and 315) */ +#define VCLK65_300 0x09 /* Index in VCLKData table (300) */ +#define VCLK108_2_300 0x14 /* Index in VCLKData table (300) */ +#define VCLK81_300 0x3f /* Index in VCLKData table (300) */ +#define VCLK108_3_300 0x42 /* Index in VCLKData table (300) */ +#define VCLK100_300 0x43 /* Index in VCLKData table (300) */ +#define VCLK34_300 0x3d /* Index in VCLKData table (300) */ +#define VCLK65_315 0x0b /* Index in (VB)VCLKData table (315) */ +#define VCLK108_2_315 0x19 /* Index in (VB)VCLKData table (315) */ +#define VCLK81_315 0x5b /* Index in (VB)VCLKData table (315) */ +#define VCLK162_315 0x21 /* Index in (VB)VCLKData table (315) */ +#define VCLK108_3_315 0x45 /* Index in VBVCLKData table (315) */ +#define VCLK100_315 0x46 /* Index in VBVCLKData table (315) */ +#define VCLK34_315 0x55 /* Index in VBVCLKData table (315) */ + +#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */ +#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */ +#define TVVCLKDIV2 0x00 /* Index relative to TVCLKBASE */ +#define TVVCLK 0x01 /* Index relative to TVCLKBASE */ +#define HiTVVCLKDIV2 0x02 /* Index relative to TVCLKBASE */ +#define HiTVVCLK 0x03 /* Index relative to TVCLKBASE */ +#define HiTVSimuVCLK 0x04 /* Index relative to TVCLKBASE */ +#define HiTVTextVCLK 0x05 /* Index relative to TVCLKBASE */ + +/* ------------------------------ */ + +#define LoadDACFlag 0x1000 +#define AfterLockCRT2 0x4000 +#define SetCRT2ToAVIDEO 0x0004 +#define SetCRT2ToSCART 0x0010 +#define Ext2StructSize 5 + +#define SetSCARTOutput 0x01 +#define AVIDEOSense 0x01 +#define SVIDEOSense 0x02 +#define SCARTSense 0x04 +#define LCDSense 0x08 +#define Monitor1Sense 0x20 +#define Monitor2Sense 0x10 +#define HiTVSense 0x40 +#define BoardTVType 0x02 +#define HotPlugFunction 0x08 +#define StStructSize 0x06 + +#define SIS_VIDEO_CAPTURE 0x00 - 0x30 +#define SIS_VIDEO_PLAYBACK 0x02 - 0x30 +#define SIS_CRT2_PORT_04 0x04 - 0x30 +#define SIS_CRT2_PORT_10 0x10 - 0x30 +#define SIS_CRT2_PORT_12 0x12 - 0x30 +#define SIS_CRT2_PORT_14 0x14 - 0x30 + +#define ADR_CRT2PtrData 0x20E +#define offset_Zurac 0x210 /* TW: Trumpion Zurac data pointer */ +#define ADR_LVDSDesPtrData 0x212 +#define ADR_LVDSCRT1DataPtr 0x214 +#define ADR_CHTVVCLKPtr 0x216 +#define ADR_CHTVRegDataPtr 0x218 + +#define LVDSDataLen 6 +#define EnableLVDSDDA 0x10 +#define LVDSDesDataLen 3 +#define ActiveNonExpanding 0x40 +#define ActiveNonExpandingShift 6 +#define ActivePAL 0x20 +#define ActivePALShift 5 +#define ModeSwitchStatus 0x0F +#define SoftTVType 0x40 +#define SoftSettingAddr 0x52 +#define ModeSettingAddr 0x53 + +#define SelectCRT1Rate 0x4 + +#define _PanelType00 0x00 +#define _PanelType01 0x08 +#define _PanelType02 0x10 +#define _PanelType03 0x18 +#define _PanelType04 0x20 +#define _PanelType05 0x28 +#define _PanelType06 0x30 +#define _PanelType07 0x38 +#define _PanelType08 0x40 +#define _PanelType09 0x48 +#define _PanelType0A 0x50 +#define _PanelType0B 0x58 +#define _PanelType0C 0x60 +#define _PanelType0D 0x68 +#define _PanelType0E 0x70 +#define _PanelType0F 0x78 + +#define PRIMARY_VGA 0 /* 1: SiS is primary vga 0:SiS is secondary vga */ +#define BIOSIDCodeAddr 0x235 /* TW: Offsets to ptrs in BIOS image */ +#define OEMUtilIDCodeAddr 0x237 +#define VBModeIDTableAddr 0x239 +#define OEMTVPtrAddr 0x241 +#define PhaseTableAddr 0x243 +#define NTSCFilterTableAddr 0x245 +#define PALFilterTableAddr 0x247 +#define OEMLCDPtr_1Addr 0x249 +#define OEMLCDPtr_2Addr 0x24B +#define LCDHPosTable_1Addr 0x24D +#define LCDHPosTable_2Addr 0x24F +#define LCDVPosTable_1Addr 0x251 +#define LCDVPosTable_2Addr 0x253 +#define OEMLCDPIDTableAddr 0x255 + +#define VBModeStructSize 5 +#define PhaseTableSize 4 +#define FilterTableSize 4 +#define LCDHPosTableSize 7 +#define LCDVPosTableSize 5 +#define OEMLVDSPIDTableSize 4 +#define LVDSHPosTableSize 4 +#define LVDSVPosTableSize 6 + +#define VB_ModeID 0 +#define VB_TVTableIndex 1 +#define VB_LCDTableIndex 2 +#define VB_LCDHIndex 3 +#define VB_LCDVIndex 4 + +#define OEMLCDEnable 0x0001 +#define OEMLCDDelayEnable 0x0002 +#define OEMLCDPOSEnable 0x0004 +#define OEMTVEnable 0x0100 +#define OEMTVDelayEnable 0x0200 +#define OEMTVFlickerEnable 0x0400 +#define OEMTVPhaseEnable 0x0800 +#define OEMTVFilterEnable 0x1000 + +#define OEMLCDPanelIDSupport 0x0080 + +/* + ============================================================= + for 315 series + ============================================================= +*/ +#define SoftDRAMType 0x80 +#define SoftSetting_OFFSET 0x52 +#define SR07_OFFSET 0x7C +#define SR15_OFFSET 0x7D +#define SR16_OFFSET 0x81 +#define SR17_OFFSET 0x85 +#define SR19_OFFSET 0x8D +#define SR1F_OFFSET 0x99 +#define SR21_OFFSET 0x9A +#define SR22_OFFSET 0x9B +#define SR23_OFFSET 0x9C +#define SR24_OFFSET 0x9D +#define SR25_OFFSET 0x9E +#define SR31_OFFSET 0x9F +#define SR32_OFFSET 0xA0 +#define SR33_OFFSET 0xA1 + +#define CR40_OFFSET 0xA2 +#define SR25_1_OFFSET 0xF6 +#define CR49_OFFSET 0xF7 + +#define VB310Data_1_2_Offset 0xB6 +#define VB310Data_4_D_Offset 0xB7 +#define VB310Data_4_E_Offset 0xB8 +#define VB310Data_4_10_Offset 0xBB + +#define RGBSenseDataOffset 0xBD +#define YCSenseDataOffset 0xBF +#define VideoSenseDataOffset 0xC1 +#define OutputSelectOffset 0xF3 + +#define ECLK_MCLK_DISTANCE 0x14 +#define VBIOSTablePointerStart 0x100 +#define StandTablePtrOffset VBIOSTablePointerStart+0x02 +#define EModeIDTablePtrOffset VBIOSTablePointerStart+0x04 +#define CRT1TablePtrOffset VBIOSTablePointerStart+0x06 +#define ScreenOffsetPtrOffset VBIOSTablePointerStart+0x08 +#define VCLKDataPtrOffset VBIOSTablePointerStart+0x0A +#define MCLKDataPtrOffset VBIOSTablePointerStart+0x0E +#define CRT2PtrDataPtrOffset VBIOSTablePointerStart+0x10 +#define TVAntiFlickPtrOffset VBIOSTablePointerStart+0x12 +#define TVDelayPtr1Offset VBIOSTablePointerStart+0x14 +#define TVPhaseIncrPtr1Offset VBIOSTablePointerStart+0x16 +#define TVYFilterPtr1Offset VBIOSTablePointerStart+0x18 +#define LCDDelayPtr1Offset VBIOSTablePointerStart+0x20 +#define TVEdgePtr1Offset VBIOSTablePointerStart+0x24 +#define CRT2Delay1Offset VBIOSTablePointerStart+0x28 + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h index 8f7e524de..9bf1a5d2b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h @@ -1,6 +1,37 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h,v 1.3 2003/02/10 01:14:16 tsi Exp $ */ - -/* OEM Data for 300 series */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h,v 1.8 2003/06/19 13:28:01 twini Exp $ */ +/* + * OEM Data for 300 series + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * Based on code by Silicon Intergrated Systems + * + */ const UCHAR SiS300_OEMTVDelay301[8][4] = { @@ -681,325 +712,147 @@ const UCHAR SiS300_Filter2[10][9][7] = } }; -const UCHAR SiS300_LCDHData[24][11][5] = { - { - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x65,0xef,0x83,0x5c,0x00}, - {0x65,0xef,0x83,0x5c,0x00}, - {0x8a,0x14,0x00,0x80,0x00}, - {0x8a,0x14,0x00,0x80,0x00} - }, - { - {0x4e,0x18,0x90,0x38,0x00}, - {0x4e,0x18,0x90,0x38,0x00}, - {0x8e,0x18,0x28,0x78,0x00}, - {0x8e,0x18,0x28,0x78,0x00}, - {0x8e,0x18,0x28,0x78,0x00}, - {0x4e,0x18,0x90,0x38,0x00}, - {0x4e,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9a,0x56,0x00}, - {0x67,0x11,0x9a,0x56,0x00}, - {0x8a,0x14,0x00,0x80,0x00}, - {0x8a,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x65,0xef,0x83,0x5c,0x00}, - {0x65,0xef,0x83,0x5c,0x00}, - {0x8a,0x14,0x00,0x80,0x00}, - {0x8a,0x14,0x00,0x80,0x00} - }, - { - {0x4e,0x18,0x90,0x38,0x00}, - {0x4e,0x18,0x90,0x38,0x00}, - {0x8e,0x18,0x28,0x78,0x00}, - {0x8e,0x18,0x28,0x78,0x00}, - {0x8e,0x18,0x28,0x78,0x00}, - {0x4e,0x18,0x90,0x38,0x00}, - {0x4e,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9a,0x56,0x00}, - {0x67,0x11,0x9a,0x56,0x00}, - {0x8a,0x14,0x00,0x80,0x00}, - {0x8a,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x67,0x91,0x84,0x5e,0x00}, - {0x65,0xef,0x83,0x5c,0x00}, - {0x65,0xef,0x83,0x5c,0x00}, - {0x8a,0x14,0x00,0x80,0x00}, - {0x8a,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x67,0x91,0x84,0x5E,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x65,0xEF,0x83,0x5C,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} - }, - { - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x8E,0x18,0x28,0x78,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x4E,0x18,0x90,0x38,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x67,0x11,0x9A,0x56,0x00}, - {0x8A,0x14,0x00,0x80,0x00}, - {0x8A,0x14,0x00,0x80,0x00} +/* Custom data for Barco iQ Pro R300 */ +const UCHAR barco_p1[2][9][7][3] = { + { + { { 0x16, 0xcf, 0x00 }, + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x19, 0x00 } + }, + { + { 0x16, 0xcf, 0x00 }, + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x1e, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x16, 0x00 } + }, + { + { 0x16, 0xcf, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x19, 0x00 }, + { 0, 0, 0 } + }, + { + { 0, 0, 0 } + }, + { + { 0x16, 0xcf, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x1e, 0x00 }, + { 0, 0, 0 } + }, + { + { 0x16, 0xd1, 0x00 }, + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x11, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x26, 0x00 } + }, + { + { 0x16, 0xd1, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x30, 0x00 }, + { 0, 0, 0 } + }, + { + { 0x16, 0x00, 0x00 }, + { 0x17, 0xa0, 0x00 }, + { 0x1a, 0xa0, 0x00 }, + { 0x1b, 0x2a, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0, 0, 0 } + }, + { + { 0x16, 0x00, 0x00 }, + { 0x17, 0xaa, 0x00 }, + { 0x1a, 0xa0, 0x00 }, + { 0x1b, 0x2a, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0, 0, 0 } + } + }, + { + { + { 0x16, 0xcf, 0x00 }, + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x19, 0x00 } + }, + { + { 0, 0, 0 } + }, + { + { 0x16, 0xcf, 0x00 }, + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x19, 0x00 }, + }, + { + { 0, 0, 0 } + }, + { + { 0x16, 0xcf, 0x00 }, + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe7, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x1e, 0x00 } + }, + { + { 0x16, 0xd1, 0x00 }, + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe6, 0x00 }, + { 0x1b, 0x11, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x26, 0x00 } + }, + { + { 0x18, 0x00, 0x00 }, + { 0x1a, 0xe0, 0x00 }, + { 0x1b, 0x26, 0x00 }, + { 0x1c, 0xff, 0x00 }, + { 0x1d, 0x1c, 0x00 }, + { 0x1e, 0x30, 0x00 }, + { 0, 0, 0 } + }, + { + { 0, 0, 0 } + }, + { + { 0, 0, 0 } + } } }; -#if 0 -const UCHAR SiS300_LCDVData[24][11][6] = { - { - { - }, -}; -#endif + + + + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h index c4415aaee..15f41d3e7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h @@ -1,14 +1,39 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h,v 1.4 2003/02/10 01:14:16 tsi Exp $ */ - -/* OEM Data for 310/325 series */ - -const UCHAR SiS310_CRT2DelayCompensation1 = 0x04; /* 301 */ - -const UCHAR SiS310_CRT2DelayCompensation2 = 0x00; /* 301B */ - -const UCHAR SiS310_CRT2DelayCompensation3 = 0x00; /* LVDS */ - -const UCHAR SiS310_LCDDelayCompensation1[] = /* 301 */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h,v 1.12 2003/08/07 15:04:41 twini Exp $ */ +/* + * OEM Data for 315/330 series + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * Based on code by Silicon Intergrated Systems + * + */ + +const UCHAR SiS310_LCDDelayCompensation_301[] = /* 301 */ { 0x00,0x00,0x00, /* 800x600 */ 0x0b,0x0b,0x0b, /* 1024x768 */ @@ -27,7 +52,8 @@ const UCHAR SiS310_LCDDelayCompensation1[] = /* 301 */ 0x00,0x00,0x00 }; -UCHAR SiS310_LCDDelayCompensation2[] = /* 30xB,LV,LVX */ +/* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */ +UCHAR SiS310_LCDDelayCompensation_650301B[] = /* 30xB,LV */ { 0x01,0x01,0x01, /* 800x600 */ 0x01,0x01,0x01, /* 1024x768 */ @@ -46,7 +72,27 @@ UCHAR SiS310_LCDDelayCompensation2[] = /* 30xB,LV,LVX */ 0x02,0x02,0x02 }; -const UCHAR SiS310_LCDDelayCompensation3[] = /* LVDS */ +/* This data is correct, so we use it instead of the table above */ +UCHAR SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB,LV */ +{ + 0x01,0x01,0x01, /* 800x600 */ + 0x0C,0x0C,0x0C, /* 1024x768 */ + 0x0C,0x0C,0x0C, /* 1280x1024 */ + 0x08,0x08,0x08, /* 640x480 */ + 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */ + 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */ + 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */ + 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */ + 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */ + 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */ + 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */ + 0x02,0x02,0x02, + 0x02,0x02,0x02, + 0x02,0x02,0x02, + 0x02,0x02,0x02 +}; + +const UCHAR SiS310_LCDDelayCompensation_LVDS650[] = /* LVDS */ { 0x00,0x00,0x00, /* 800x600 */ 0x00,0x00,0x00, /* 1024x768 */ @@ -65,47 +111,28 @@ const UCHAR SiS310_LCDDelayCompensation3[] = /* LVDS */ 0x00,0x00,0x00 }; -const UCHAR SiS310_LCDDelayCompensation4[] = /* 650 */ -{ - 0x01,0x01,0x01, /* 800x600 (guessed)*/ - 0x01,0x01,0x01, /* 1024x768 */ - 0x01,0x01,0x01, /* 1280x1024 */ - 0x01,0x01,0x01, /* 640x480 (unknown) */ - 0x01,0x01,0x01, /* 1024x600 (unknown) */ - 0x01,0x01,0x01, /* 1152x864 (unknown) */ - 0x01,0x01,0x01, /* 1280x960 (guessed) */ - 0x01,0x01,0x01, /* 1152x768 (unknown) */ - 0x01,0x01,0x01, /* 1400x1050 */ - 0x01,0x01,0x01, /* 1280x768 (guessed) */ - 0x01,0x01,0x01, /* 1600x1200 */ - 0x01,0x01,0x01, - 0x01,0x01,0x01, - 0x01,0x01,0x01, - 0x01,0x01,0x01 -}; - -const UCHAR SiS310_LCDDelayCompensation5[] = /* 650 LVX */ +const UCHAR SiS310_LCDDelayCompensation_LVDS740[] = /* LVDS */ { - 0x01,0x01,0x01, /* 800x600 (guessed) */ - 0x01,0x01,0x01, /* 1024x768 */ - 0x01,0x01,0x01, /* 1280x1024 */ - 0x01,0x01,0x01, /* 640x480 (unknown) */ - 0x01,0x01,0x01, /* 1024x600 (unknown) */ - 0x01,0x01,0x01, /* 1152x864 (unknown) */ - 0x01,0x01,0x01, /* 1280x960 (guessed) */ - 0x01,0x01,0x01, /* 1152x768 (unknown) */ - 0x01,0x01,0x01, /* 1400x1050 */ - 0x01,0x01,0x01, /* 1280x768 (guessed) */ - 0x01,0x01,0x01, /* 1600x1200 */ - 0x01,0x01,0x01, - 0x01,0x01,0x01, - 0x01,0x01,0x01, - 0x01,0x01,0x01 + 0x03,0x03,0x03, /* 800x600 */ + 0x03,0x03,0x03, /* 1024x768 */ + 0x03,0x03,0x03, /* 1280x1024 */ + 0x03,0x03,0x03, /* 640x480 (unknown) */ + 0x03,0x03,0x03, /* 1024x600 (unknown) */ + 0x03,0x03,0x03, /* 1152x864 (unknown) */ + 0x03,0x03,0x03, /* 1280x960 (guessed) */ + 0x03,0x03,0x03, /* 1152x768 (unknown) */ + 0x03,0x03,0x03, /* 1400x1050 */ + 0x03,0x03,0x03, /* 1280x768 (guessed) */ + 0x03,0x03,0x03, /* 1600x1200 */ + 0x00,0x00,0x00, + 0x00,0x00,0x00, + 0x00,0x00,0x00, + 0x00,0x00,0x00 }; -const UCHAR SiS310_LCDDelayCompensation6[] = /* M650/651 */ +const UCHAR SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */ { - 0x33,0x33,0x33, /* 800x600 (guessed) */ + 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */ 0x33,0x33,0x33, /* 1024x768 */ 0x33,0x33,0x33, /* 1280x1024 */ 0x33,0x33,0x33, /* 640x480 (unknown) */ @@ -122,7 +149,7 @@ const UCHAR SiS310_LCDDelayCompensation6[] = /* M650/651 */ 0x33,0x33,0x33 }; -const UCHAR SiS310_LCDDelayCompensation7[] = /* M650/651 301LVX */ +const UCHAR SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */ { 0x33,0x33,0x33, /* 800x600 (guessed) */ 0x33,0x33,0x33, /* 1024x768 */ @@ -141,49 +168,42 @@ const UCHAR SiS310_LCDDelayCompensation7[] = /* M650/651 301LVX */ 0x33,0x33,0x33 }; -const UCHAR SiS310_TVDelayCompensation1[] = /* 301 */ +const UCHAR SiS310_TVDelayCompensation_301[] = /* 301 */ { 0x02,0x02, /* NTSC Enhanced, Standard */ 0x02,0x02, /* PAL */ 0x08,0x0b /* HiVision */ }; -const UCHAR SiS310_TVDelayCompensation2[] = /* 301B;LV */ +const UCHAR SiS310_TVDelayCompensation_301B[] = /* 30xB, 30xLV */ { 0x03,0x03, 0x03,0x03, 0x03,0x03 }; -const UCHAR SiS310_TVDelayCompensation3[] = /* LVDS */ -{ - 0x0a,0x0a, - 0x0a,0x0a, - 0x0a,0x0a -}; - -const UCHAR SiS310_TVDelayCompensation4[] = /* 650 */ +const UCHAR SiS310_TVDelayCompensation_740301B[] = /* 740 + 30xB (30xLV?) */ { - 0x03,0x03, - 0x03,0x03, - 0x03,0x03 + 0x05,0x05, + 0x05,0x05, + 0x05,0x05 }; -const UCHAR SiS310_TVDelayCompensation5[] = /* 650 LVX */ +const UCHAR SiS310_TVDelayCompensation_LVDS[] = /* LVDS */ { - 0x03,0x03, - 0x03,0x03, - 0x03,0x03 + 0x0a,0x0a, + 0x0a,0x0a, + 0x0a,0x0a }; -const UCHAR SiS310_TVDelayCompensation6[] = /* M650, 651 */ +const UCHAR SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */ { 0x33,0x33, 0x33,0x33, 0x33,0x33 }; -const UCHAR SiS310_TVDelayCompensation7[] = /* M650, 651, LVX */ +const UCHAR SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 302LV */ { 0x33,0x33, 0x33,0x33, @@ -373,5 +393,124 @@ const UCHAR SiS310_TVPhaseIncr2[3][2][4] = } }; +/* OEM data for Compaq Presario 3045US */ +static const SiS_LCDDataStruct SiS310_ExtCompaq1280x1024Data[] = +{ + { 211, 60,1024, 501,1688,1066}, + { 211, 60,1024, 508,1688,1066}, + { 211, 60,1024, 501,1688,1066}, + { 211, 60,1024, 508,1688,1066}, + { 32, 15,1696, 501,1696,1066}, + { 212, 75,1024, 621,1696,1066}, + { 4, 3,1696, 810,1696,1066}, + { 1, 1,1696,1066,1696,1066} +}; + +static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_1[] = +{ + {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}}, + {{0x35,0x1B,0xA0,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}}, + {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}}, + {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}}, + {{0x45,0x1C,0x20,0x3F,0xFF,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}}, + {{0x49,0x1C,0x40,0x7F,0xFF,0xAD,0x23,0x0A,0x07,0xF3,0x8A,0x12}}, + {{0x4C,0x1C,0x18,0x2F,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}} +}; + +static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_2[] = +{ + {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}}, + {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}}, + {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}}, + {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}}, + {{0x33,0x13,0x01,0x0D,0xFD,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}}, + {{0x3F,0x1B,0x3D,0x49,0x39,0x54,0x23,0xC0,0x27,0x66,0x30,0x42}}, + {{0x33,0x1B,0x91,0x9D,0x8D,0x8C,0x23,0xF8,0x27,0x9E,0x68,0x42}}, + {{0x43,0x24,0x11,0x1D,0x0D,0xCC,0x23,0x38,0x37,0xDE,0xA8,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xEA,0x23,0x0A,0x07,0x32,0xC6,0x42}} +}; + +static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_3[] = +{ + {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}, + {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}} +}; + +static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_1[] = +{ + {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}, + {{0x2C,0x12,0x9A,0xAE,0x88,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}, + {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x38,0x13,0x16,0x0C,0xE6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}, + {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}, + {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}} +}; + +static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_2[] = +{ + {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}}, + {{0x2C,0x12,0x38,0x55,0x2F,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}}, + {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}}, + {{0x2C,0x12,0x38,0x55,0x2F,0xE0,0x12,0xB1,0x47,0x30,0x71,0x33}}, + {{0x2D,0x12,0x79,0x96,0x70,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}}, + {{0x29,0x12,0xB5,0xD2,0xAC,0xF4,0x12,0xD9,0x47,0x44,0x99,0x33}}, + {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, +#if 0 + {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}}, + {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}}, + {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}}, + {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}} +#endif +}; + +static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_3[] = +{ + {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, /* Corrected */ + {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, + {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, + {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, + {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x25,0x13,0xC9,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}} +}; + +static const SiS_LVDSDesStruct Clevo1024x768Des_1[] = +{ + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 } +}; + +static const SiS_LVDSDesStruct Clevo1024x768Des_2[] = +{ + { 1184, 622 }, + { 1184, 597 }, + { 1184, 622 }, + { 1184, 597 }, + { 1152, 622 }, + { 1232, 722 }, + { 0, 0 }, + { 0, 794 }, + { 0, 0 } +}; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h index 039d968b9..323065847 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h @@ -1,18 +1,14 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h,v 1.2 2003/02/10 01:14:16 tsi Exp $ */ /* OS depending defines */ /* The choices are: */ -/* #define WINCE_HEADER */ /* Incomplete! */ -/* #define WIN2000 */ /* Incomplete! */ -/* #define TC */ /* Incomplete! */ /* #define LINUX_KERNEL */ /* Kernel framebuffer */ #define LINUX_XF86 /* XFree86 */ /**********************************************************************/ #ifdef LINUX_KERNEL /* ----------------------------*/ - #include <linux/config.h> + #ifdef CONFIG_FB_SIS_300 #define SIS300 #endif @@ -21,62 +17,25 @@ #define SIS315H #endif -#else /* if not LINUX_KERNEL --------------------- */ -/* #define SIS300*/ -#define SIS315H - -#endif /* if LINUX_KERNEL ------------------------ */ +#if 1 +#define SISFBACCEL /* Include 2D acceleration */ +#endif -#ifdef LINUX_XF86 /* Linux Xfree86 ---------------- */ +#endif +#ifdef LINUX_XF86 /* ----------------------------- */ #define SIS300 -/* #define SIS315H */ /* TW: done above */ +#define SIS315H #endif /**********************************************************************/ -#ifdef TC -#endif -#ifdef WIN2000 -#endif -#ifdef WINCE_HEADER -#endif -#ifdef LINUX_XF86 -#endif -#ifdef LINUX_KERNEL -#endif -/**********************************************************************/ -#ifdef TC -#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize); -#endif -#ifdef WIN2000 -#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value); -#endif -#ifdef WINCE_HEADER -#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize); -#endif -#ifdef LINUX_XF86 -#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) -#endif #ifdef LINUX_KERNEL #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) +#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length) #endif -/**********************************************************************/ - -/**********************************************************************/ -#ifdef TC -#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length); -#endif -#ifdef WIN2000 -#define SiS_MemoryCopy(Destination,Soruce,Length) /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/ -#endif -#ifdef WINCE_HEADER -#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length); -#endif #ifdef LINUX_XF86 -#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length) -#endif -#ifdef LINUX_KERNEL +#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length) #endif @@ -107,16 +66,16 @@ #endif /* InPortLong */ /**********************************************************************/ -/* TC */ +/* LINUX KERNEL */ /**********************************************************************/ -#ifdef TC -#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v)) -#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v)) -#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v)) -#define InPortByte(p) inp((unsigned short)(p)) -#define InPortWord(p) inp((unsigned short)(p)) -#define InPortLong(p) ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p))) +#ifdef LINUX_KERNEL +#define OutPortByte(p,v) outb((u8)(v),(u16)(p)) +#define OutPortWord(p,v) outw((u16)(v),(u16)(p)) +#define OutPortLong(p,v) outl((u32)(v),(u16)(p)) +#define InPortByte(p) inb((u16)(p)) +#define InPortWord(p) inw((u16)(p)) +#define InPortLong(p) inl((u16)(p)) #endif /**********************************************************************/ @@ -132,38 +91,3 @@ #define InPortLong(p) inl((CARD16)(p)) #endif -#ifdef LINUX_KERNEL -#define OutPortByte(p,v) outb((u8)(v),(u16)(p)) -#define OutPortWord(p,v) outw((u16)(v),(u16)(p)) -#define OutPortLong(p,v) outl((u32)(v),(u16)(p)) -#define InPortByte(p) inb((u16)(p)) -#define InPortWord(p) inw((u16)(p)) -#define InPortLong(p) inl((u16)(p)) -#endif - -/**********************************************************************/ -/* WIN 2000 */ -/**********************************************************************/ - -#ifdef WIN2000 -#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v)) -#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v)) -#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v)) -#define InPortByte(p) VideoPortReadPortUchar ((PUCHAR) (p)) -#define InPortWord(p) VideoPortReadPortUshort ((PUSHORT) (p)) -#define InPortLong(p) VideoPortReadPortUlong ((PULONG) (p)) -#endif - - -/**********************************************************************/ -/* WIN CE */ -/**********************************************************************/ - -#ifdef WINCE_HEADER -#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v)) -#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v)) -#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v)) -#define InPortByte(p) READ_PORT_UCHAR ((PUCHAR) (p)) -#define InPortWord(p) READ_PORT_USHORT ((PUSHORT) (p)) -#define InPortLong(p) READ_PORT_ULONG ((PULONG) (p)) -#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h index f854e33d3..00aed5b4c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h @@ -1,106 +1,960 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h,v 1.42 2003/08/10 21:25:37 twini Exp $ */ /* - * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Main global data and definitions + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. + * Authors: + * + * ? + * Thomas Winischhofer <thomas@winischhofer.net> + * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h,v 1.8 1999/06/20 15:02:55 dawes Exp $ */ - #ifndef _SIS_H #define _SIS_H_ +/* Always unlock the registers (should be set!) */ +#define UNLOCK_ALWAYS + +#define SISDRIVERVERSIONYEAR 3 +#define SISDRIVERVERSIONMONTH 8 +#define SISDRIVERVERSIONDAY 10 +#define SISDRIVERREVISION 1 + +#define SISDRIVERIVERSION (SISDRIVERVERSIONYEAR << 16) | (SISDRIVERVERSIONMONTH << 8) \ + | SISDRIVERVERSIONDAY | (SISDRIVERREVISION << 24) + +#if 0 +#define TWDEBUG /* for debugging */ +#endif + +#if 0 +#include "siscp.H" +#else +#undef SIS_CP +#endif + +#include "xf86Pci.h" #include "xf86Cursor.h" -#include "xaa.h" +#include "xf86_ansic.h" +#include "xf86xv.h" #include "compiler.h" +#include "xaa.h" #include "vgaHW.h" +#include "vbe.h" +#include "osdef.h" +#include "vgatypes.h" +#include "vstruct.h" + +#ifdef XF86DRI +#include "xf86drm.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "GL/glxint.h" +#include "sis_dri.h" +#endif + +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0) +typedef unsigned long IOADDRESS; +#endif + +#if 1 +#define SISDUALHEAD /* Include Dual Head code */ +#endif + +#if 1 +#define SISMERGED /* Include Merged-FB mode */ +#endif + +#ifdef SISMERGED +#if 1 +#define SISXINERAMA /* Include SiS Pseudo-Xinerama for MergedFB mode */ +#define SIS_XINERAMA_MAJOR_VERSION 1 +#define SIS_XINERAMA_MINOR_VERSION 1 +#endif +#endif + +#if 0 /* Include code for cycling CRT2 type via keyboard */ +#define CYCLECRT2 /* (not functional yet) */ +#endif + +#if 1 +#define SISGAMMA /* Include code for gamma correction */ +#endif + +#if 1 /* Include code for color hardware cursors */ +#define SIS_ARGB_CURSOR +#endif + +#ifdef SISMERGED +#ifdef SISXINERAMA +#define NEED_REPLIES /* ? */ +#define EXTENSION_PROC_ARGS void * +#include "extnsionst.h" /* required */ +#include "panoramiXproto.h" /* required */ +#endif +#endif + +/* For SiS315/550/650/740/330/660 - these should be moved elsewhere! */ +#ifndef PCI_CHIP_SIS315H +#define PCI_CHIP_SIS315H 0x0310 +#endif +#ifndef PCI_CHIP_SIS315 +#define PCI_CHIP_SIS315 0x0315 +#endif +#ifndef PCI_CHIP_SIS315PRO +#define PCI_CHIP_SIS315PRO 0x0325 +#endif +#ifndef PCI_CHIP_SIS550 +#define PCI_CHIP_SIS550 0x5315 /* 550_VGA */ +#endif +#ifndef PCI_CHIP_SIS650 +#define PCI_CHIP_SIS650 0x6325 /* 650_VGA and 740_VGA */ +#endif +#ifndef PCI_CHIP_SIS330 +#define PCI_CHIP_SIS330 0x0330 +#endif +#ifndef PCI_CHIP_SIS660 +#define PCI_CHIP_SIS660 0x6330 /* 660_VGA and 760_VGA */ +#endif + +#define SIS_NAME "SIS" +#define SIS_DRIVER_NAME "sis" +#define SIS_MAJOR_VERSION 0 +#define SIS_MINOR_VERSION 7 +#define SIS_PATCHLEVEL 0 +#define SIS_CURRENT_VERSION ((SIS_MAJOR_VERSION << 16) | \ + (SIS_MINOR_VERSION << 8) | SIS_PATCHLEVEL ) + +/* pSiS->Flags (old series only) */ +#define SYNCDRAM 0x00000001 +#define RAMFLAG 0x00000002 +#define ESS137xPRESENT 0x00000004 +#define SECRETFLAG 0x00000008 +#define A6326REVAB 0x00000010 +#define MMIOMODE 0x00010000 +#define LFBQMODE 0x00020000 +#define AGPQMODE 0x00040000 +#define UMA 0x80000000 + +#define BIOS_BASE 0xC0000 +#define BIOS_SIZE 0x10000 + +#define SR_BUFFER_SIZE 5 +#define CR_BUFFER_SIZE 5 + +#define SIS_VBFlagsVersion 1 + +/* VBFlags - if anything is changed here, increase VBFlagsVersion! */ +#define CRT2_DEFAULT 0x00000001 +#define CRT2_LCD 0x00000002 /* TW: Never change the order of the CRT2_XXX entries */ +#define CRT2_TV 0x00000004 /* (see SISCycleCRT2Type()) */ +#define CRT2_VGA 0x00000008 +#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA) +#define DISPTYPE_DISP2 CRT2_ENABLE +#define TV_NTSC 0x00000010 +#define TV_PAL 0x00000020 +#define TV_HIVISION 0x00000040 +#define TV_HIVISION_LV 0x00000080 +#define TV_TYPE (TV_NTSC | TV_PAL | TV_HIVISION | TV_HIVISION_LV) +#define TV_AVIDEO 0x00000100 +#define TV_SVIDEO 0x00000200 +#define TV_SCART 0x00000400 +#define TV_INTERFACE (TV_AVIDEO | TV_SVIDEO | TV_SCART | TV_CHSCART | TV_CHHDTV) +#define VB_USELCDA 0x00000800 +#define TV_PALM 0x00001000 +#define TV_PALN 0x00002000 +#define TV_CHSCART 0x00008000 +#define TV_CHHDTV 0x00010000 +#define VGA2_CONNECTED 0x00040000 +#define DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */ +#define DISPTYPE_DISP1 DISPTYPE_CRT1 +#define VB_301 0x00100000 /* Video bridge type */ +#define VB_301B 0x00200000 +#define VB_302B 0x00400000 +#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */ +#define VB_LVDS 0x01000000 +#define VB_CHRONTEL 0x02000000 +#define VB_301LV 0x04000000 +#define VB_302LV 0x08000000 +#define VB_30xLV VB_301LV +#define VB_30xLVX VB_302LV +#define VB_TRUMPION 0x10000000 +#define VB_VIDEOBRIDGE (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV| \ + VB_LVDS|VB_CHRONTEL|VB_TRUMPION) +#define VB_SISBRIDGE (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV) +#define SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */ +#define VB_DISPMODE_SINGLE SINGLE_MODE /* alias */ +#define MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */ +#define VB_DISPMODE_MIRROR MIRROR_MODE /* alias */ +#define DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */ +#define VB_DISPMODE_DUAL DUALVIEW_MODE /* alias */ +#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE) /* TW */ + +/* TW: pSiS->VBLCDFlags */ +#define VB_LCD_320x480 0x00000001 /* TW: DSTN/FSTN for 550 */ +#define VB_LCD_640x480 0x00000002 +#define VB_LCD_800x600 0x00000004 +#define VB_LCD_1024x768 0x00000008 +#define VB_LCD_1280x1024 0x00000010 +#define VB_LCD_1280x960 0x00000020 +#define VB_LCD_1600x1200 0x00000040 +#define VB_LCD_2048x1536 0x00000080 +#define VB_LCD_1400x1050 0x00000100 +#define VB_LCD_1152x864 0x00000200 +#define VB_LCD_1152x768 0x00000400 +#define VB_LCD_1280x768 0x00000800 +#define VB_LCD_1024x600 0x00001000 +#define VB_LCD_640x480_2 0x00002000 /* DSTN/FSTN */ +#define VB_LCD_640x480_3 0x00004000 /* DSTN/FSTN */ +#define VB_LCD_848x480 0x00008000 /* LVDS only, otherwise handled as custom */ +#define VB_LCD_BARCO1366 0x20000000 +#define VB_LCD_CUSTOM 0x40000000 +#define VB_LCD_EXPANDING 0x80000000 + +/* pSiS->MiscFlags */ +#define MISC_CRT1OVERLAY 0x00000001 /* Current display mode supports overlay */ +#define MISC_PANELLINKSCALER 0x00000002 /* Panel link is currently scaling */ + +/* More or less useful macros (although we often use pSiS->VGAEngine instead) */ +#define SIS_IS_300_CHIPSET (pSiS->Chipset == PCI_CHIP_SIS300) || \ + (pSiS->Chipset == PCI_CHIP_SIS630) || \ + (pSiS->Chipset == PCI_CHIP_SIS540) || \ + (pSiS->Chipset == PCI_CHIP_SIS730) + +#define SIS_IS_315_CHIPSET (pSiS->Chipset == PCI_CHIP_SIS315) || \ + (pSiS->Chipset == PCI_CHIP_SIS315H) || \ + (pSiS->Chipset == PCI_CHIP_SIS315PRO) || \ + (pSiS->Chipset == PCI_CHIP_SIS550) || \ + (pSiS->Chipset == PCI_CHIP_SIS650) || \ + (pSiS->Chipset == PCI_CHIP_SIS330) || \ + (pSiS->Chipset == PCI_CHIP_SIS660) || \ + (pSiS->Chipset == PCI_CHIP_SIS760) + +/* SiS6326Flags */ +#define SIS6326_HASTV 0x00000001 +#define SIS6326_TVSVIDEO 0x00000002 +#define SIS6326_TVCVBS 0x00000004 +#define SIS6326_TVPAL 0x00000008 +#define SIS6326_TVDETECTED 0x00000010 +#define SIS6326_TVON 0x80000000 +#define HW_DEVICE_EXTENSION SIS_HW_DEVICE_INFO + +#ifdef DEBUG +#define PDEBUG(p) p +#else +#define PDEBUG(p) +#endif + +typedef unsigned long ULong; +typedef unsigned short UShort; +typedef unsigned char UChar; + +/* VGA engine types */ +#define UNKNOWN_VGA 0 +#define SIS_530_VGA 1 +#define SIS_OLD_VGA 2 +#define SIS_300_VGA 3 +#define SIS_315_VGA 4 /* Includes Xabre; see ChipFlags */ + +/* oldChipset */ +#define OC_UNKNOWN 0 +#define OC_SIS86201 1 +#define OC_SIS86202 2 +#define OC_SIS6205A 3 +#define OC_SIS6205B 4 +#define OC_SIS82204 5 +#define OC_SIS6205C 6 +#define OC_SIS6225 7 +#define OC_SIS5597 8 +#define OC_SIS6326 9 +#define OC_SIS530A 11 +#define OC_SIS530B 12 +#define OC_SIS620 13 + +/* Chrontel type */ +#define CHRONTEL_700x 0 +#define CHRONTEL_701x 1 + +/* ChipFlags */ +/* Use only lower 16 bit for chip id! (sisctrl) */ +#define SiSCF_LARGEOVERLAY 0x00000001 +#define SiSCF_Is651 0x00000002 +#define SiSCF_IsM650 0x00000004 +#define SiSCF_IsM652 0x00000008 +#define SiSCF_IsM653 0x00000010 +#define SiSCF_Is652 0x00000020 +#define SiSCF_Is65x (SiSCF_Is651 | SiSCF_IsM650 | SiSCF_IsM652 | SiSCF_IsM653 | SiSCF_Is652) +#define SiSCF_IsM660 0x00000100 +#define SiSCF_IsM760 0x00000200 +#define SiSCF_Is66x (SiSCF_IsM660 | SiSCF_IsM760) +#define SiSCF_XabreCore 0x00010000 +#define SiSCF_Glamour3 0x40000000 +#define SiSCF_Integrated 0x80000000 + + +/* SiS Direct Xv-API */ +#define SiS_SD_IS300SERIES 0x00000001 +#define SiS_SD_IS315SERIES 0x00000002 +#define SiS_SD_IS330SERIES 0x00000004 +#define SiS_SD_SUPPORTPALMN 0x00000008 /* tv chip supports pal-m, pal-n */ +#define SiS_SD_SUPPORT2OVL 0x00000010 /* set = 2 overlays, 1 = support SWITCHCRT xv prop */ +#define SiS_SD_SUPPORTTVPOS 0x00000020 /* supports changing tv position */ +#define SiS_SD_ISDUALHEAD 0x00000040 /* Driver is in dual head mode */ +#define SiS_SD_ISMERGEDFB 0x00000080 /* Driver is in merged fb mode */ +#define SiS_SD_ISDHSECONDHEAD 0x00000100 /* Dual head: This is CRT1 (=second head) */ +#define SiS_SD_ISDHXINERAMA 0x00000200 /* Dual head: We are running Xinerama */ +#define SiS_SD_VBHASSCART 0x00000400 /* videobridge has SCART instead of VGA2 */ +#define SiS_SD_ISDEPTH8 0x00000800 /* Depth is 8, no independent gamma correction */ +#define SiS_SD_SUPPORTSOVER 0x00001000 /* Support for Chrontel Super Overscan */ +#define SiS_SD_ENABLED 0x00002000 /* sisctrl is enabled (by option) */ +#define SiS_SD_PSEUDOXINERAMA 0x00004000 /* pseudo xinerama is active */ + +#define SIS_DIRECTKEY 0x3145792 + +/* SiSCtrl: Check mode for CRT2 */ +#define SiS_CF2_LCD 0x01 +#define SiS_CF2_TV 0x02 +#define SiS_CF2_VGA2 0x04 +#define SiS_CF2_TVPAL 0x08 +#define SiS_CF2_TVNTSC 0x10 +#define SiS_CF2_TVPALM 0x20 +#define SiS_CF2_TVPALN 0x40 + +/* For backup of register contents */ typedef struct { - unsigned char sisRegs3x4[0x100]; - unsigned char sisRegs3C4[0x100]; - unsigned char sisRegs3C2[0x100]; + unsigned char sisRegs3C4[0x50]; + unsigned char sisRegs3D4[0x90]; + unsigned char sisRegs3C2; + unsigned char sisCapt[0x60]; + unsigned char sisVid[0x50]; + unsigned char VBPart1[0x50]; + unsigned char VBPart2[0x50]; + unsigned char VBPart3[0x50]; + unsigned char VBPart4[0x50]; + unsigned short ch70xx[64]; + unsigned long sisMMIO85C0; + unsigned char sis6326tv[0x46]; + unsigned long sisRegsPCI50, sisRegsPCIA0; } SISRegRec, *SISRegPtr; -#define SISPTR(p) ((SISPtr)((p)->driverPrivate)) +typedef struct _sisModeInfoPtr { + int width; + int height; + int bpp; + int n; + struct _sisModeInfoPtr *next; +} sisModeInfoRec, *sisModeInfoPtr; + +/* SISFBLayout is mainly there because of DGA. It holds the + * current layout parameters needed for acceleration and other + * stuff. When switching mode using DGA, these are set up + * accordingly and not necessarily match pScrn's. Therefore, + * driver modules should read these values instead of pScrn's. + */ +typedef struct { + int bitsPerPixel; /* = pScrn->bitsPerPixel */ + int depth; /* = pScrn->depth */ + int displayWidth; /* = pScrn->displayWidth */ + DisplayModePtr mode; /* = pScrn->currentMode */ +} SISFBLayout; +/* Dual head private entity structure */ +#ifdef SISDUALHEAD typedef struct { - ScrnInfoPtr pScrn; - pciVideoPtr PciInfo; - PCITAG PciTag; - EntityInfoPtr pEnt; - int Chipset; - int ChipRev; - int DACtype; - int HwBpp; - int BppShift; - CARD32 IOAddress; - CARD32 FbAddress; - unsigned char * IOBase; + ScrnInfoPtr pScrn_1; + ScrnInfoPtr pScrn_2; + unsigned char * BIOS; + SiS_Private * SiS_Pr; + int CRT1ModeNo; /* Current display mode for CRT1 */ + DisplayModePtr CRT1DMode; /* Current display mode for CRT1 */ + int CRT2ModeNo; /* Current display mode for CRT2 */ + DisplayModePtr CRT2DMode; /* Current display mode for CRT2 */ + Bool CRT2IsCustom; + int refCount; + int lastInstance; /* number of entities */ + Bool DisableDual; /* Emergency flag */ + Bool ErrorAfterFirst; /* Emergency flag: Error after first init -> Abort second */ + Bool HWCursor; /* Backup master settings for use on slave */ + Bool TurboQueue; + int ForceCRT2Type; + int OptTVStand; + int OptTVOver; + int OptTVSOver; + int OptROMUsage; + int OptUseOEM; + int PDC; + Bool NoAccel; + int forceCRT1; + int DSTN, FSTN; + Bool XvOnCRT2; + int maxUsedClock; /* Max used pixelclock on master head */ + unsigned long masterFbAddress; /* Framebuffer addresses and sizes */ + unsigned long masterFbSize; + unsigned long slaveFbAddress; + unsigned long slaveFbSize; + unsigned char * FbBase; /* VRAM linear address */ + unsigned char * IOBase; /* MMIO linear address */ + unsigned short MapCountIOBase; /* map/unmap queue counter */ + unsigned short MapCountFbBase; /* map/unmap queue counter */ + Bool forceUnmapIOBase; /* ignore counter and unmap */ + Bool forceUnmapFbBase; /* ignore counter and unmap */ #ifdef __alpha__ - unsigned char * IOBaseDense; -#endif - unsigned char * FbBase; - CARD32 IOAccelAddress; - unsigned char * IOAccel; - long FbMapSize; - Bool NoAccel; - Bool HWCursor; - Bool UsePCIRetry; - Bool TurboQueue; - Bool ValidWidth; - Bool FastVram; - Bool ClipEnabled; - int MemClock; - int MinClock; - int MaxClock; - int Xdirection; - int Ydirection; - int sisPatternReg[4]; - int ROPReg; /* for sis530 */ - int CommandReg; /* for sis530 */ - int DstX; - int DstY; - unsigned char * XAAScanlineColorExpandBuffers[2]; - SISRegRec SavedReg; - SISRegRec ModeReg; - CARD32 AccelFlags; - xf86CursorInfoPtr CursorInfoRec; - XAAInfoRecPtr AccelInfoRec; - CloseScreenProcPtr CloseScreen; - unsigned int (*ddc1Read)(ScrnInfoPtr); + unsigned char * IOBaseDense; /* MMIO for Alpha platform */ + unsigned short MapCountIOBaseDense; + Bool forceUnmapIOBaseDense; /* ignore counter and unmap */ +#endif + int chtvlumabandwidthcvbs; /* TV settings for Chrontel TV encoder */ + int chtvlumabandwidthsvideo; + int chtvlumaflickerfilter; + int chtvchromabandwidth; + int chtvchromaflickerfilter; + int chtvcvbscolor; + int chtvtextenhance; + int chtvcontrast; + int sistvedgeenhance; /* TV settings for SiS bridge */ + int sistvantiflicker; + int sistvsaturation; + int sistvcolcalibc; + int sistvcolcalibf; + int sistvcfilter; + int sistvyfilter; + int tvxpos, tvypos; + int tvxscale, tvyscale; + int ForceTVType; + int chtvtype; + int NonDefaultPAL; + unsigned short tvx, tvy; + unsigned char p2_01, p2_02, p2_1f, p2_20; + unsigned char p2_44, p2_45, p2_46; + unsigned long sistvccbase; + unsigned char p2_35, p2_36, p2_37, p2_38, p2_48, p2_49, p2_4a; + unsigned char p2_0a, p2_2f, p2_30, p2_47; + unsigned char scalingp1[9], scalingp4[9]; + unsigned short cursorBufferNum; + BOOLEAN restorebyset; + BOOLEAN CRT1gamma, CRT2gamma; + int curxvcrtnum; + int UsePanelScaler; + int AllowHotkey; + BOOLEAN enablesisctrl; +#ifdef SIS_CP + SIS_CP_H_ENT +#endif +} SISEntRec, *SISEntPtr; +#endif + +#define SISPTR(p) ((SISPtr)((p)->driverPrivate)) +#define XAAPTR(p) ((XAAInfoRecPtr)(SISPTR(p)->AccelInfoPtr)) + +/* Relative merge position */ +typedef enum { + sisLeftOf, + sisRightOf, + sisAbove, + sisBelow, + sisClone +} SiSScrn2Rel; + +typedef struct { + ScrnInfoPtr pScrn; /* -------------- DON'T INSERT ANYTHING HERE --------------- */ + pciVideoPtr PciInfo; /* -------- OTHERWISE sis_dri.so MUST BE RECOMPILED -------- */ + PCITAG PciTag; + EntityInfoPtr pEnt; + int Chipset; + int ChipRev; + int VGAEngine; /* see above */ + int hasTwoOverlays; /* Chipset supports two video overlays? */ + HW_DEVICE_EXTENSION sishw_ext; /* For new mode switching code */ + SiS_Private * SiS_Pr; /* For new mode switching code */ + int DSTN; /* For 550 FSTN/DSTN; set by option, no detection */ + unsigned long FbAddress; /* VRAM physical address (in DHM: for each Fb!) */ + unsigned long realFbAddress; /* For DHM/PCI mem mapping: store global FBAddress */ + unsigned char * FbBase; /* VRAM virtual linear address */ + CARD32 IOAddress; /* MMIO physical address */ + unsigned char * IOBase; /* MMIO linear address */ + IOADDRESS IODBase; /* Base of PIO memory area */ +#ifdef __alpha__ + unsigned char * IOBaseDense; /* MMIO for Alpha platform */ +#endif + CARD16 RelIO; /* Relocated IO Ports baseaddress */ + unsigned char * BIOS; + int MemClock; + int BusWidth; + int MinClock; + int MaxClock; + int Flags; /* HW config flags */ + long FbMapSize; /* Used for Mem Mapping - DON'T CHANGE THIS */ + long availMem; /* Really available Fb mem (minus TQ, HWCursor) */ + unsigned long maxxfbmem; /* limit fb memory X is to use to this (KB) */ + unsigned long sisfbMem; /* heapstart of sisfb (if running) */ +#ifdef SISDUALHEAD + unsigned long dhmOffset; /* Offset to memory for each head (0 or ..) */ +#endif + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; + unsigned char OldMode; /* Back old modeNo (if available) */ + Bool NoAccel; + Bool NoXvideo; + Bool XvOnCRT2; /* see sis_opt.c */ + Bool HWCursor; + Bool UsePCIRetry; + Bool TurboQueue; + int VESA; + int ForceCRT2Type; + int OptTVStand; + int OptTVOver; + int OptROMUsage; + int UseCHOverScan; + Bool ValidWidth; + Bool FastVram; /* now unused */ + int forceCRT1; + Bool CRT1changed; + unsigned char oldCR17, oldCR63, oldSR1F; + unsigned char oldCR32; + unsigned char newCR32; + unsigned long VBFlags; /* Video bridge configuration */ + unsigned long VBFlags_backup; /* Backup for SlaveMode-modes */ + unsigned long VBLCDFlags; /* Moved LCD panel size bits here */ + int ChrontelType; /* CHRONTEL_700x or CHRONTEL_701x */ + int PDC; /* PanelDelayCompensation */ + short scrnOffset; /* Screen pitch (data) */ + short scrnPitch; /* Screen pitch (display; regarding interlace) */ + short DstColor; + int xcurrent; /* for temp use in accel */ + int ycurrent; /* for temp use in accel */ + long SiS310_AccelDepth; /* used in accel for 315 series */ + int Xdirection; /* for temp use in accel */ + int Ydirection; /* for temp use in accel */ + int sisPatternReg[4]; + int ROPReg; + int CommandReg; + int MaxCMDQueueLen; + int CurCMDQueueLen; + int MinCMDQueueLen; + CARD16 CursorSize; /* Size of HWCursor area (bytes) */ + CARD32 cursorOffset; /* see sis_driver.c and sis_cursor.c */ + int DstX; + int DstY; + unsigned char * XAAScanlineColorExpandBuffers[2]; + CARD32 AccelFlags; + Bool ClipEnabled; + Bool DoColorExpand; + SISRegRec SavedReg; + SISRegRec ModeReg; + xf86CursorInfoPtr CursorInfoPtr; + XAAInfoRecPtr AccelInfoPtr; + CloseScreenProcPtr CloseScreen; + unsigned int (*ddc1Read)(ScrnInfoPtr); + Bool (*ModeInit)(ScrnInfoPtr pScrn, DisplayModePtr mode); + void (*SiSSave)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SiSSave2)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SiSSave3)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SiSSaveLVDSChrontel)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SiSRestore)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SiSRestore2)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SiSRestore3)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SiSRestoreLVDSChrontel)(ScrnInfoPtr pScrn, SISRegPtr sisreg); + void (*SetThreshold)(ScrnInfoPtr pScrn, DisplayModePtr mode, + unsigned short *Low, unsigned short *High); + void (*LoadCRT2Palette)(ScrnInfoPtr pScrn, int numColors, + int *indicies, LOCO *colors, VisualPtr pVisual); + + int cmdQueueLen; /* Current cmdQueueLength (for 2D and 3D) */ + int *cmdQueueLenPtr; + unsigned long agpHandle; + CARD32 agpAddr; + unsigned char *agpBase; + unsigned int agpSize; + CARD32 agpCmdBufAddr; + unsigned char *agpCmdBufBase; + unsigned int agpCmdBufSize; + unsigned int agpCmdBufFree; + Bool irqEnabled; + int irq; + + int ColorExpandRingHead; + int ColorExpandRingTail; + int PerColorExpandBufferSize; + int ColorExpandBufferNumber; + int ColorExpandBufferCountMask; + unsigned char *ColorExpandBufferAddr[32]; + int ColorExpandBufferScreenOffset[32]; + int ImageWriteBufferSize; + unsigned char *ImageWriteBufferAddr; + + int Rotate; + void (*PointerMoved)(int index, int x, int y); + + /* ShadowFB support */ + Bool ShadowFB; + unsigned char *ShadowPtr; + int ShadowPitch; + +#ifdef XF86DRI + Bool directRenderingEnabled; + DRIInfoPtr pDRIInfo; + int drmSubFD; + int numVisualConfigs; + __GLXvisualConfig* pVisualConfigs; + SISConfigPrivPtr pVisualConfigsPriv; + SISRegRec DRContextRegs; +#endif + + XF86VideoAdaptorPtr adaptor; + ScreenBlockHandlerProcPtr BlockHandler; + void (*VideoTimerCallback)(ScrnInfoPtr, Time); + + OptionInfoPtr Options; + unsigned char LCDon; +#ifdef SISDUALHEAD + Bool BlankCRT1, BlankCRT2; +#endif + Bool Blank; + unsigned char BIOSModeSave; + int CRT1off; /* 1=CRT1 off, 0=CRT1 on */ + CARD16 LCDheight; /* Vertical resolution of LCD panel */ + CARD16 LCDwidth; /* Horizontal resolution of LCD panel */ + vbeInfoPtr pVbe; /* For VESA mode switching */ + CARD16 vesamajor; + CARD16 vesaminor; + VbeInfoBlock *vbeInfo; + int UseVESA; + sisModeInfoPtr SISVESAModeList; + xf86MonPtr monitor; + CARD16 maxBytesPerScanline; + CARD32 *pal, *savedPal; + int mapPhys, mapOff, mapSize; + int statePage, stateSize, stateMode; + CARD8 *fonts; + CARD8 *state, *pstate; + void *base, *VGAbase; +#ifdef SISDUALHEAD + BOOL DualHeadMode; /* TRUE if we use dual head mode */ + BOOL SecondHead; /* TRUE is this is the second head */ + SISEntPtr entityPrivate; /* Ptr to private entity (see above) */ + BOOL SiSXinerama; /* Do we use Xinerama mode? */ +#endif + SISFBLayout CurrentLayout; /* Current framebuffer layout */ + Bool (*i2cInit)(ScrnInfoPtr);/* I2C stuff (unused) */ + I2CBusPtr I2C; + USHORT SiS_DDC2_Index; + USHORT SiS_DDC2_Data; + USHORT SiS_DDC2_Clk; + BOOL Primary; /* Display adapter is primary */ + xf86Int10InfoPtr pInt; /* Our int10 */ + int oldChipset; /* Type of old chipset */ + CARD32 RealVideoRam; /* 6326 can only address 4MB, but TQ can be above */ + CARD32 CmdQueLenMask; /* Mask of queue length in MMIO register */ + CARD32 CmdQueLenFix; /* Fix value to subtract from QueLen (530/620) */ + CARD32 CmdQueMaxLen; /* (6326/5597/5598) Amount of cmds the queue can hold */ + CARD32 TurboQueueLen; /* For future use */ + CARD32 detectedCRT2Devices; /* detected CRT2 devices before mask-out */ + Bool NoHostBus; /* Enable/disable 5597/5598 host bus */ + Bool noInternalModes; /* Use our own default modes? */ + int OptUseOEM; /* Use internal OEM data? */ + int chtvlumabandwidthcvbs; /* TV settings for Chrontel TV encoder */ + int chtvlumabandwidthsvideo; + int chtvlumaflickerfilter; + int chtvchromabandwidth; + int chtvchromaflickerfilter; + int chtvcvbscolor; + int chtvtextenhance; + int chtvcontrast; + int sistvedgeenhance; /* TV settings for SiS bridges */ + int sistvantiflicker; + int sistvsaturation; + int sistvcolcalibc; + int sistvcolcalibf; + int sistvcfilter; + int sistvyfilter; + int OptTVSOver; /* Chrontel 7005: Superoverscan */ + int tvxpos, tvypos; + int tvxscale, tvyscale; + int SiS6326Flags; /* SiS6326 TV settings */ + int sis6326enableyfilter; + int sis6326yfilterstrong; + int sis6326tvplug; + int sis6326fscadjust; + BOOL donttrustpdc; /* Don't trust the detected PDC */ + unsigned char sisfbpdc; + unsigned char sisfblcda; + int sisfbscalelcd; + unsigned long sisfbspecialtiming; + int NoYV12; /* Disable Xv YV12 support (old series) */ + unsigned char postVBCR32; + int newFastVram; /* Replaces FastVram */ + int ForceTVType; + int NonDefaultPAL; + unsigned long lockcalls; /* Count unlock calls for debug */ + unsigned short tvx, tvy; /* Backup TV position registers */ + unsigned char p2_01, p2_02, p2_1f, p2_20; /* Backup TV position registers */ + unsigned short tvx1, tvx2, tvx3, tvy1; /* Backup TV position registers */ + unsigned char p2_44, p2_45, p2_46; + unsigned long sistvccbase; + unsigned char p2_35, p2_36, p2_37, p2_38, p2_48, p2_49, p2_4a; + unsigned char p2_0a, p2_2f, p2_30, p2_47; + unsigned char scalingp1[9], scalingp4[9]; + BOOLEAN ForceCursorOff; + BOOLEAN HaveCustomModes; + BOOLEAN IsCustom; + DisplayModePtr backupmodelist; + int chtvtype; + Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation; + Atom xvAutopaintColorKey, xvSetDefaults, xvSwitchCRT; + Atom xvDisableGfx, xvDisableGfxLR, xvTVXPosition, xvTVYPosition; + Atom xvDisableColorkey, xvUseChromakey, xvChromaMin, xvChromaMax; + Atom xvInsideChromakey, xvYUVChromakey; + Atom xv_QVF, xv_QVV, xv_USD, xv_SVF, xv_QDD, xv_TAF, xv_TSA, xv_TEE, xv_GSF; + Atom xv_TTE, xv_TCO, xv_TCC, xv_TCF, xv_TLF, xv_CMD, xv_CMDR, xv_CT1, xv_SGA; + Atom xv_GDV, xv_GHI, xv_OVR, xv_GBI, xv_TXS, xv_TYS, xv_CFI, xv_COC, xv_COF; + Atom xv_YFI, xv_GSS, xv_BRR, xv_BRG, xv_BRB, xv_PBR, xv_PBG, xv_PBB; + BOOLEAN xv_sisdirectunlocked; + unsigned long xv_sd_result; + int CRT1isoff; +#ifdef SIS_CP + SIS_CP_H +#endif + unsigned long ChipFlags; + unsigned long SiS_SD_Flags; + BOOLEAN UseHWARGBCursor; + int OptUseColorCursor; + int OptUseColorCursorBlend; + CARD32 OptColorCursorBlendThreshold; + unsigned short cursorBufferNum; + int vb; + BOOLEAN restorebyset; + BOOLEAN nocrt2ddcdetection; + BOOLEAN forcecrt2redetection; + BOOLEAN CRT1gamma, CRT2gamma; + int XvDefCon, XvDefBri, XvDefHue, XvDefSat; + BOOLEAN XvDefDisableGfx, XvDefDisableGfxLR; + BOOLEAN XvUseMemcpy; + BOOLEAN XvUseChromaKey, XvDisableColorKey; + BOOLEAN XvInsideChromaKey, XvYUVChromaKey; + int XvChromaMin, XvChromaMax; + BOOLEAN disablecolorkeycurrent; + CARD32 colorKey; + CARD32 MiscFlags; + int UsePanelScaler; + Time AccelRenderTime; + FBLinearPtr AccelLinearScratch; + void (*AccelRenderCallback)(ScrnInfoPtr); + float zClearVal; + unsigned long bClrColor, dwColor; + int AllowHotkey; + BOOLEAN enablesisctrl; + short Video_MaxWidth, Video_MaxHeight; + int FSTN; + BOOLEAN AddedPlasmaModes; + short scrnPitch2; + CARD32 CurFGCol, CurBGCol; + unsigned char * CurMonoSrc; + CARD32 * CurARGBDest; + int GammaBriR, GammaBriG, GammaBriB; + int GammaPBriR, GammaPBriG, GammaPBriB; +#ifdef SISMERGED + Bool MergedFB; + SiSScrn2Rel CRT2Position; + char * CRT2HSync; + char * CRT2VRefresh; + char * MetaModes; + ScrnInfoPtr CRT2pScrn; + DisplayModePtr CRT1Modes; + DisplayModePtr CRT1CurrentMode; + int CRT1frameX0; + int CRT1frameY0; + int CRT1frameX1; + int CRT1frameY1; + Bool CheckForCRT2; + Bool IsCustomCRT2; + BOOLEAN HaveCustomModes2; + int maxCRT1_X1, maxCRT1_X2, maxCRT1_Y1, maxCRT1_Y2; + int maxCRT2_X1, maxCRT2_X2, maxCRT2_Y1, maxCRT2_Y2; + int maxClone_X1, maxClone_X2, maxClone_Y1, maxClone_Y2; +#ifdef SISXINERAMA + Bool UseSiSXinerama; + Bool CRT2IsScrn0; + ExtensionEntry *XineramaExtEntry; + int SiSXineramaVX, SiSXineramaVY; + Bool AtLeastOneNonClone; +#endif +#endif } SISRec, *SISPtr; -/* Prototypes */ +typedef struct _ModeInfoData { + int mode; + VbeModeInfoBlock *data; + VbeCRTCInfoBlock *block; +} ModeInfoData; + +#define SDMPTR(x) ((SiSMergedDisplayModePtr)(x->currentMode->Private)) +#define CDMPTR ((SiSMergedDisplayModePtr)(pSiS->CurrentLayout.mode->Private)) -unsigned int SiSddc1Read(ScrnInfoPtr pScrn); -void SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); -void SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); -Bool SiSInit(ScrnInfoPtr pScrn, DisplayModePtr mode); -Bool SiSAccelInit(ScreenPtr pScreen); -Bool SiS2AccelInit(ScreenPtr pScreen); -int SiSMclk(void); -int sisMemBandWidth(ScrnInfoPtr pScrn); -Bool SiSHWCursorInit(ScreenPtr pScreen); +#define BOUND(test,low,hi) { \ + if(test < low) test = low; \ + if(test > hi) test = hi; } + +#define REBOUND(low,hi,test) { \ + if(test < low) { \ + hi += test-low; \ + low = test; } \ + if(test > hi) { \ + low += test-hi; \ + hi = test; } } + +typedef struct _MergedDisplayModeRec { + DisplayModePtr CRT1; + DisplayModePtr CRT2; + SiSScrn2Rel CRT2Position; +} SiSMergedDisplayModeRec, *SiSMergedDisplayModePtr; + + +typedef struct _region { + int x0,x1,y0,y1; +} region; + +typedef struct _myhddctiming { + int whichone; + unsigned char mask; + float rate; +} myhddctiming; + +typedef struct _myvddctiming { + int whichone; + unsigned char mask; + int rate; +} myvddctiming; + +typedef struct _myddcstdmodes { + int hsize; + int vsize; + int refresh; + float hsync; +} myddcstdmodes; + +typedef struct _pdctable { + int subsysVendor; + int subsysCard; + int pdc; + char *vendorName; + char *cardName; +} pdctable; + +typedef struct _chswtable { + int subsysVendor; + int subsysCard; + char *vendorName; + char *cardName; +} chswtable; + +typedef struct _customttable { + unsigned short chipID; + char *biosversion; + char *biosdate; + unsigned long bioschksum; + unsigned short biosFootprintAddr[5]; + unsigned char biosFootprintData[5]; + unsigned short pcisubsysvendor; + unsigned short pcisubsyscard; + char *vendorName; + char *cardName; + unsigned long SpecialID; + char *optionName; +} customttable; + +#ifdef SISMERGED +#ifdef SISXINERAMA +typedef struct _SiSXineramaData { + int x; + int y; + int width; + int height; +} SiSXineramaData; +#endif +#endif +extern void sisSaveUnlockExtRegisterLock(SISPtr pSiS, unsigned char *reg1, unsigned char *reg2); +extern void sisRestoreExtRegisterLock(SISPtr pSiS, unsigned char reg1, unsigned char reg2); +extern void SiSOptions(ScrnInfoPtr pScrn); +extern const OptionInfoRec * SISAvailableOptions(int chipid, int busid); +extern void SiSSetup(ScrnInfoPtr pScrn); +extern void SISVGAPreInit(ScrnInfoPtr pScrn); +extern Bool SiSAccelInit(ScreenPtr pScreen); +extern Bool SiS300AccelInit(ScreenPtr pScreen); +extern Bool SiS315AccelInit(ScreenPtr pScreen); +extern Bool SiS530AccelInit(ScreenPtr pScreen); +extern Bool SiSHWCursorInit(ScreenPtr pScreen); +extern Bool SISDGAInit(ScreenPtr pScreen); +extern void SISInitVideo(ScreenPtr pScreen); +extern void SIS6326InitVideo(ScreenPtr pScreen); +extern void SiS_SetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn, int val); +extern void SiS_SetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn, int val); +extern void SiS_SetCHTVlumaflickerfilter(ScrnInfoPtr pScrn, int val); +extern void SiS_SetCHTVchromabandwidth(ScrnInfoPtr pScrn, int val); +extern void SiS_SetCHTVchromaflickerfilter(ScrnInfoPtr pScrn, int val); +extern void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val); +extern void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val); +extern void SiS_SetCHTVcontrast(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSISTVedgeenhance(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSISTVantiflicker(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSISTVsaturation(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSISTVcfilter(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSISTVyfilter(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSISTVcolcalib(ScrnInfoPtr pScrn, int val, Bool coarse); +extern void SiS_SetSIS6326TVantiflicker(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSIS6326TVenableyfilter(ScrnInfoPtr pScrn, int val); +extern void SiS_SetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn, int val); +extern void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val); +extern void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val); +extern void SiS_SetTVxscale(ScrnInfoPtr pScrn, int val); +extern void SiS_SetTVyscale(ScrnInfoPtr pScrn, int val); +extern Bool SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags); +extern Bool SISCheckModeIndexForCRT2Type(ScrnInfoPtr pScrn, unsigned short cond, unsigned short index); +extern Bool SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff); +extern int SiS_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn); +extern int SiS_GetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn); +extern int SiS_GetCHTVlumaflickerfilter(ScrnInfoPtr pScrn); +extern int SiS_GetCHTVchromabandwidth(ScrnInfoPtr pScrn); +extern int SiS_GetCHTVchromaflickerfilter(ScrnInfoPtr pScrn); +extern int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn); +extern int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn); +extern int SiS_GetCHTVcontrast(ScrnInfoPtr pScrn); +extern int SiS_GetSISTVedgeenhance(ScrnInfoPtr pScrn); +extern int SiS_GetSISTVantiflicker(ScrnInfoPtr pScrn); +extern int SiS_GetSISTVsaturation(ScrnInfoPtr pScrn); +extern int SiS_GetSISTVcfilter(ScrnInfoPtr pScrn); +extern int SiS_GetSISTVyfilter(ScrnInfoPtr pScrn); +extern int SiS_GetSISTVcolcalib(ScrnInfoPtr pScrn, Bool coarse); +extern int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn); +extern int SiS_GetSIS6326TVenableyfilter(ScrnInfoPtr pScrn); +extern int SiS_GetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn); +extern int SiS_GetTVxposoffset(ScrnInfoPtr pScrn); +extern int SiS_GetTVyposoffset(ScrnInfoPtr pScrn); +extern int SiS_GetTVxscale(ScrnInfoPtr pScrn); +extern int SiS_GetTVyscale(ScrnInfoPtr pScrn); #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c index 42a6323b8..881fc34bc 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c @@ -1,106 +1,199 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c,v 1.2 2000/02/12 23:07:58 dawes Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c,v 1.19 2003/08/07 12:52:23 twini Exp $ */ /* + * 2D Acceleration for SiS300, SiS540, SiS630, SiS730, SiS530, SiS620 + * + * Copyright Xavier Ducoin <x.ducoin@lectra.com> + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. * - * Acceleration for SiS300 SiS630 SiS540. - * It is done in a separate file because the register formats are - * very different from the previous chips. + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * + * Authors: + * + * Xavier Ducoin <x.ducoin@lectra.com> + * Thomas Winischhofer <thomas@winischhofer.net> * - * - * Xavier Ducoin <x.ducoin@lectra.com> */ #if 0 #define DEBUG #endif -#include <xf86.h> -#include <xf86_OSproc.h> -#include <xf86_ansic.h> - -#include <xf86PciInfo.h> -#include <xf86Pci.h> - -#include <miline.h> - -#include <xaa.h> -#include <xaalocal.h> -#include <xf86fbman.h> +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "compiler.h" +#include "xaa.h" +#include "xaalocal.h" #include "sis.h" #include "sis300_accel.h" +#ifdef SISDUALHEAD +/* TW: This is the offset to the memory for each head */ +#define HEADOFFSET (pSiS->dhmOffset) +#endif -#ifdef DEBUG -static void MMIODump(ScrnInfoPtr pScrn); +#undef STSCE /* TW: Use/Don't use ScreenToScreenColorExpand - does not work */ + +#undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides + * illegal trapezoid data (left and right edges cross each other + * sometimes) which causes drawing errors. Further, I have not found + * out how to draw polygones with a height greater than 127... + */ + +#undef INCL_RENDER /* Use/Don't use RENDER extension acceleration */ + /* DO NOT ENABLE THIS. The code for this contained in this + * file is purely experimental and is not even supposed to + * do anything but crash the accelerator engine! + */ + +#ifdef INCL_RENDER +#ifdef RENDER +#include "mipict.h" +#include "dixstruct.h" +#endif #endif +static void SiSInitializeAccelerator(ScrnInfoPtr pScrn); static void SiSSync(ScrnInfoPtr pScrn); static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, - int xdir, int ydir, int rop, - unsigned int planemask, int trans_color); + int xdir, int ydir, int rop, + unsigned int planemask, int trans_color); static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, - int x1, int y1, int x2, int y2, - int width, int height); + int x1, int y1, int x2, int y2, + int width, int height); static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color, - int rop, unsigned int planemask); + int rop, unsigned int planemask); static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, - int x, int y, int w, int h); + int x, int y, int w, int h); +#ifdef TRAP +static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR); +#endif static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, - int rop, unsigned int planemask); + int rop, unsigned int planemask); static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, - int y1, int x2, int y2, int flags); + int y1, int x2, int y2, int flags); static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn, - int x, int y, int len, int dir); + int x, int y, int len, int dir); static void SiSSetupForDashedLine(ScrnInfoPtr pScrn, - int fg, int bg, int rop, unsigned int planemask, - int length, unsigned char *pattern); + int fg, int bg, int rop, unsigned int planemask, + int length, unsigned char *pattern); static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, - int x1, int y1, int x2, int y2, - int flags, int phase); + int x1, int y1, int x2, int y2, + int flags, int phase); static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, int fg, int bg, - int rop, unsigned int planemask); + int patx, int paty, int fg, int bg, + int rop, unsigned int planemask); static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, - int x, int y, int w, int h); + int patx, int paty, + int x, int y, int w, int h); +#ifdef TRAP +static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, + int patx, int paty, + int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR ); +#endif +#if 0 static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, int rop, - unsigned int planemask, - int trans_color); + int patx, int paty, int rop, + unsigned int planemask, + int trans_color); static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, - int x, int y, int w, int h); + int patx, int paty, + int x, int y, int w, int h); +#endif +#if 0 static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, - int fg, int bg, - int rop, unsigned int planemask); + int fg, int bg, + int rop, unsigned int planemask); static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn, - int x, int y, int w, int h, int skipleft); + int x, int y, int w, int h, int skipleft); +#endif +#ifdef STSCE static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, - int fg, int bg, - int rop, unsigned int planemask); + int fg, int bg, + int rop, unsigned int planemask); static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, - int x, int y, int w, int h, - int srcx, int srcy, int skipleft); + int x, int y, int w, int h, + int srcx, int srcy, int skipleft); +#endif +static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft); +static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#ifdef INCL_RENDER +#ifdef RENDER +extern Bool SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, + int op, CARD16 red, CARD16 green, + CARD16 blue, CARD16 alpha, + int alphaType, CARD8 *alphaPtr, + int alphaPitch, int width, + int height, int flags); + +extern Bool SiSSetupForCPUToScreenTexture( ScrnInfoPtr pScrn, + int op, int texType, CARD8 *texPtr, + int texPitch, int width, + int height, int flags); + +extern void SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, + int dstx, int dsty, + int srcx, int srcy, + int width, int height); +extern CARD32 SiSAlphaTextureFormats[2]; +extern CARD32 SiSTextureFormats[2]; +CARD32 SiSAlphaTextureFormats[2] = { PICT_a8, 0 }; +CARD32 SiSTextureFormats[2] = { PICT_a8r8g8b8, 0 }; +#endif +#endif + +#ifdef SISDUALHEAD +static void SiSRestoreAccelState(ScrnInfoPtr pScrn); +#endif -void +static void SiSInitializeAccelerator(ScrnInfoPtr pScrn) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); pSiS->DoColorExpand = FALSE; } Bool SiS300AccelInit(ScreenPtr pScreen) { - XAAInfoRecPtr infoPtr; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSiS = SISPTR(pScrn); - int reservedFbSize, UsableFbSize; - BoxRec Avail; + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + int topFB; + int reservedFbSize; + int UsableFbSize; + unsigned char *AvailBufBase; + BoxRec Avail; + int i; pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; @@ -108,106 +201,178 @@ SiS300AccelInit(ScreenPtr pScreen) SiSInitializeAccelerator(pScrn); infoPtr->Flags = LINEAR_FRAMEBUFFER | - OFFSCREEN_PIXMAPS | - PIXMAP_CACHE | - NO_PLANEMASK; + OFFSCREEN_PIXMAPS | + PIXMAP_CACHE; /* sync */ infoPtr->Sync = SiSSync; - /* BitBlt */ - infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; - infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; - infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY; - - - /* solid fills */ - infoPtr->SetupForSolidFill = SiSSetupForSolidFill; - infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect; - infoPtr->SolidFillFlags = NO_PLANEMASK; - - - /* solid line */ - infoPtr->SetupForSolidLine = SiSSetupForSolidLine; - infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; - infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine; - infoPtr->SolidFillFlags = NO_PLANEMASK; - - - /* dashed line */ - infoPtr->SetupForDashedLine = SiSSetupForDashedLine; - infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine; - infoPtr->DashPatternMaxLength = 64; - infoPtr->DashedLineFlags = NO_PLANEMASK | - LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; - - - /* 8x8 mono pattern fill */ - infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill; - infoPtr->SubsequentMono8x8PatternFillRect = - SiSSubsequentMonoPatternFill; - infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | - HARDWARE_PATTERN_SCREEN_ORIGIN | - HARDWARE_PATTERN_PROGRAMMED_BITS | - NO_TRANSPARENCY | - BIT_ORDER_IN_BYTE_MSBFIRST ; - - - /* 8x8 color pattern fill - infoPtr->SetupForColor8x8PatternFill = - SiSSetupForColorPatternFill; - infoPtr->SubsequentColor8x8PatternFillRect = - SiSSubsequentColorPatternFill; - infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK | - HARDWARE_PATTERN_SCREEN_ORIGIN | - HARDWARE_PATTERN_PROGRAMMED_BITS ; -*/ - - - /* CPU To Screen Color Expand */ - infoPtr->SetupForCPUToScreenColorExpandFill = - SiSSetupForCPUToScreenColorExpand; - infoPtr->SubsequentCPUToScreenColorExpandFill = - SiSSubsequentCPUToScreenColorExpand; - infoPtr->SetupForScreenToScreenColorExpandFill = - SiSSetupForScreenToScreenColorExpand; - infoPtr->ColorExpandRange = PATREGSIZE; - infoPtr->ColorExpandBase = pSiS->IOBase+PBR(0); - infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK | - BIT_ORDER_IN_BYTE_MSBFIRST | - NO_TRANSPARENCY | - SYNC_AFTER_COLOR_EXPAND | - HARDWARE_PATTERN_SCREEN_ORIGIN | - HARDWARE_PATTERN_PROGRAMMED_BITS ; - - - - /* Screen To Screen Color Expand - infoPtr->SetupForScreenToScreenColorExpandFill = - SiSSetupForScreenToScreenColorExpand; - infoPtr->SubsequentScreenToScreenColorExpandFill = - SiSSubsequentScreenToScreenColorExpand; - infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK | - BIT_ORDER_IN_BYTE_MSBFIRST | - SYNC_AFTER_COLOR_EXPAND | - NO_TRANSPARENCY; -*/ + /* Acceleration only supported at 8, 16 and 32 bpp */ + if((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) && + (pScrn->bitsPerPixel != 32)) + return FALSE; + + /* TW: Although SiS states that the 300 series supports a + * virtual framebuffer of 4096x4096, the 2D accelerator + * does not seem to know that. If the destination bitmap + * pitch is > 8192 (which easily happens in 32bpp mode), + * the accelerator engine collapses. + * TODO: Find out about the 530 and 620 + */ + + if(pSiS->scrnOffset < 8192) { + + /* screen to screen copy - TW: We now support transparent copies */ + infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; + infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | + TRANSPARENCY_GXCOPY_ONLY; + + /* solid fills */ + infoPtr->SetupForSolidFill = SiSSetupForSolidFill; + infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect; +#ifdef TRAP + infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap; +#endif + infoPtr->SolidFillFlags = NO_PLANEMASK; + + /* solid line */ + infoPtr->SetupForSolidLine = SiSSetupForSolidLine; + infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; + infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine; + infoPtr->SolidLineFlags = NO_PLANEMASK; + + /* dashed line */ + infoPtr->SetupForDashedLine = SiSSetupForDashedLine; + infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine; + infoPtr->DashPatternMaxLength = 64; + infoPtr->DashedLineFlags = NO_PLANEMASK | + LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; + + /* 8x8 mono pattern fill */ + infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill; +#ifdef TRAP + infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap; +#endif + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS | + NO_TRANSPARENCY | + BIT_ORDER_IN_BYTE_MSBFIRST ; + +#ifdef STSCE + /* Screen To Screen Color Expand */ + /* TW: The hardware does support this the way we need it */ + infoPtr->SetupForScreenToScreenColorExpandFill = + SiSSetupForScreenToScreenColorExpand; + infoPtr->SubsequentScreenToScreenColorExpandFill = + SiSSubsequentScreenToScreenColorExpand; + infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST ; +#endif +#if 0 + /* CPU To Screen Color Expand --- implement another instead of this one! */ + infoPtr->SetupForCPUToScreenColorExpandFill = + SiSSetupForCPUToScreenColorExpand; + infoPtr->SubsequentCPUToScreenColorExpandFill = + SiSSubsequentCPUToScreenColorExpand; + infoPtr->ColorExpandRange = PATREGSIZE; + infoPtr->ColorExpandBase = pSiS->IOBase+PBR(0); + infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST | + NO_TRANSPARENCY | + SYNC_AFTER_COLOR_EXPAND | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS ; +#endif + + /* per-scanline color expansion (using indirect method) */ + if(pSiS->VGAEngine == SIS_530_VGA) { + pSiS->ColorExpandBufferNumber = 4; + pSiS->ColorExpandBufferCountMask = 0x03; + } else { + pSiS->ColorExpandBufferNumber = 16; + pSiS->ColorExpandBufferCountMask = 0x0F; + } + pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; + infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; + infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0]; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + SiSSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + SiSSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + SiSSubsequentColorExpandScanline; + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Virtual screen width too large for accelerator engine\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Accelerator engine and Xv disabled\n"); + pSiS->NoXvideo = TRUE; + } + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + infoPtr->RestoreAccelState = SiSRestoreAccelState; + } +#endif /* init Frame Buffer Manager */ - reservedFbSize = 0; - if (pSiS->TurboQueue) reservedFbSize += 1024*512; - if (pSiS->HWCursor) reservedFbSize += 4096; - UsableFbSize = pSiS->FbMapSize - reservedFbSize; + topFB = pSiS->maxxfbmem; + + reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize; + + UsableFbSize = topFB - reservedFbSize; + + /* Layout: (Sizes do not reflect correct proportions) + * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~| + * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series + * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~| + * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620 + * topFB + */ + + AvailBufBase = pSiS->FbBase + UsableFbSize; + for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) { + pSiS->ColorExpandBufferAddr[i] = AvailBufBase + + i * pSiS->PerColorExpandBufferSize; + pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize + + i * pSiS->PerColorExpandBufferSize; + } Avail.x1 = 0; Avail.y1 = 0; Avail.x2 = pScrn->displayWidth; - Avail.y2 = UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Frame Buffer From (%d,%d) To (%d,%d)\n", - Avail.x1, Avail.y1, Avail.x2, Avail.y2); - xf86InitFBManager(pScreen, &Avail); + Avail.y2 = (UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1; + + if(Avail.y2 < 0) Avail.y2 = 32767; + + if(Avail.y2 < pScrn->currentMode->VDisplay) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Not enough video RAM for accelerator. At least " + "%dKB needed, %dKB available\n", + ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */ + * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8, + pSiS->maxxfbmem/1024); + pSiS->NoAccel = TRUE; + pSiS->NoXvideo = TRUE; + XAADestroyInfoRec(pSiS->AccelInfoPtr); + pSiS->AccelInfoPtr = NULL; + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Frame Buffer From (%d,%d) To (%d,%d)\n", + Avail.x1, Avail.y1, Avail.x2, Avail.y2); + + xf86InitFBManager(pScreen, &Avail); return(XAAInit(pScreen, infoPtr)); } @@ -220,426 +385,1075 @@ SiSSync(ScrnInfoPtr pScrn) PDEBUG(ErrorF("SiSSync()\n")); - if (pSiS->DoColorExpand) - SiSDoCMD pSiS->DoColorExpand = FALSE; SiSIdle } -static int sisALUConv[] = +#ifdef SISDUALHEAD +static void +SiSRestoreAccelState(ScrnInfoPtr pScrn) { - 0x00, /* dest = 0; 0, GXclear, 0 */ - 0x88, /* dest &= src; DSa, GXand, 0x1 */ - 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */ - 0xCC, /* dest = src; S, GXcopy, 0x3 */ - 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */ - 0xAA, /* dest = dest; D, GXnoop, 0x5 */ - 0x66, /* dest = ^src; DSx, GXxor, 0x6 */ - 0xEE, /* dest |= src; DSo, GXor, 0x7 */ - 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */ - 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */ - 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ - 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */ - 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */ - 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */ - 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ - 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ + SISPtr pSiS = SISPTR(pScrn); + + /* TW: We don't need to do anything special here; forcing the + * other head to re-read the CmdQueLen is not necessary: + * After the Sync in RestoreAccelState(), the real queue + * length is always larger than (or at least equal to) + * the amount stored in CmdQueueLen of the other head, + * so the only thing that might happen is one unnecessary + * Sync on the other head. I think we can live with that. + */ + pSiS->DoColorExpand = FALSE; + SiSIdle +} +#endif + +static const int sisALUConv[] = +{ + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0x88, /* dest &= src; DSa, GXand, 0x1 */ + 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */ + 0xCC, /* dest = src; S, GXcopy, 0x3 */ + 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x66, /* dest = ^src; DSx, GXxor, 0x6 */ + 0xEE, /* dest |= src; DSo, GXor, 0x7 */ + 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */ + 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */ + 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */ + 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */ + 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ }; /* same ROP but with Pattern as Source */ -static int sisPatALUConv[] = +static const int sisPatALUConv[] = { - 0x00, /* dest = 0; 0, GXclear, 0 */ - 0xA0, /* dest &= src; DPa, GXand, 0x1 */ - 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */ - 0xF0, /* dest = src; P, GXcopy, 0x3 */ - 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */ - 0xAA, /* dest = dest; D, GXnoop, 0x5 */ - 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */ - 0xFA, /* dest |= src; DPo, GXor, 0x7 */ - 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */ - 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */ - 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ - 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */ - 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */ - 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */ - 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */ - 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0xA0, /* dest &= src; DPa, GXand, 0x1 */ + 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */ + 0xF0, /* dest = src; P, GXcopy, 0x3 */ + 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */ + 0xFA, /* dest |= src; DPo, GXor, 0x7 */ + 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */ + 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */ + 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */ + 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */ + 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ }; static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, - int xdir, int ydir, int rop, - unsigned int planemask, int trans_color) + int xdir, int ydir, int rop, + unsigned int planemask, int trans_color) { - SISPtr pSiS = SISPTR(pScrn); - XAAInfoRecPtr pXAA = XAAPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n", - xdir, ydir, rop, planemask, trans_color)); -/* - ErrorF("XAAInfoPtr->UsingPixmapCache = %s\n" - "XAAInfoPtr->CanDoMono8x8 = %s\n" - "XAAInfoPtr->CanDoColor8x8 = %s\n" - "XAAInfoPtr->CachePixelGranularity = %d\n" - "XAAInfoPtr->MaxCacheableTileWidth = %d\n" - "XAAInfoPtr->MaxCacheableTileHeight = %d\n" - "XAAInfoPtr->MaxCacheableStippleWidth = %d\n" - "XAAInfoPtr->MaxCacheableStippleHeight = %d\n" - "XAAInfoPtr->MonoPatternPitch = %d\n" - "XAAInfoPtr->CacheWidthMono8x8Pattern = %d\n" - "XAAInfoPtr->CacheHeightMono8x8Pattern = %d\n" - "XAAInfoPtr->ColorPatternPitch = %d\n" - "XAAInfoPtr->CacheWidthColor8x8Pattern = %d\n" - "XAAInfoPtr->CacheHeightColor8x8Pattern = %d\n" - "XAAInfoPtr->CacheColorExpandDensity = %d\n" - "XAAInfoPtr->maxOffPixWidth = %d\n" - "XAAInfoPtr->maxOffPixHeight= %d\n" - "XAAInfoPtr->NeedToSync = %s\n" - "\n", - pXAA->UsingPixmapCache ? "True" : "False", - pXAA->CanDoMono8x8 ? "True" : "False", - pXAA->CanDoColor8x8 ? "True" : "False", - pXAA->CachePixelGranularity, - pXAA->MaxCacheableTileWidth, - pXAA->MaxCacheableTileHeight, - pXAA->MaxCacheableStippleWidth, - pXAA->MaxCacheableStippleHeight, - pXAA->MonoPatternPitch, - pXAA->CacheWidthMono8x8Pattern, - pXAA->CacheHeightMono8x8Pattern, - pXAA->ColorPatternPitch, - pXAA->CacheWidthColor8x8Pattern, - pXAA->CacheHeightColor8x8Pattern, - pXAA->CacheColorExpandDensity, - pXAA->maxOffPixWidth, - pXAA->maxOffPixHeight, - pXAA->NeedToSync ? "True" : "False"); -*/ - - SiSSetupSRCBase(0) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + xdir, ydir, rop, planemask, trans_color)); + + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupSRCPitch(pSiS->scrnOffset) - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupROP(sisALUConv[rop]) - if (xdir > 0) SiSSetupCMDFlag(X_INC) - if (ydir > 0) SiSSetupCMDFlag(Y_INC) + if(trans_color != -1) { + SiSSetupROP(0x0A) + SiSSetupSRCTrans(trans_color) + SiSSetupCMDFlag(TRANSPARENT_BITBLT) + } else { + SiSSetupROP(sisALUConv[rop]) + } + if(xdir > 0) { + SiSSetupCMDFlag(X_INC) + } + if(ydir > 0) { + SiSSetupCMDFlag(Y_INC) + } } static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, - int src_x, int src_y, int dst_x, int dst_y, - int width, int height) + int src_x, int src_y, int dst_x, int dst_y, + int width, int height) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long srcbase, dstbase; PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n", - src_x, src_y, dst_x, dst_y, width, height)); + src_x, src_y, dst_x, dst_y, width, height)); + + srcbase = dstbase = 0; + if(src_y >= 2048) { + srcbase = pSiS->scrnOffset * src_y; + src_y = 0; + } + if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { + dstbase = pSiS->scrnOffset * dst_y; + dst_y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; + } +#endif + SiSSetupSRCBase(srcbase); + SiSSetupDSTBase(dstbase); - if (!(pSiS->CommandReg & X_INC)) { + if(!(pSiS->CommandReg & X_INC)) { src_x += width-1; dst_x += width-1; } - if (!(pSiS->CommandReg & Y_INC)) { + if(!(pSiS->CommandReg & Y_INC)) { src_y += height-1; dst_y += height-1; } SiSSetupRect(width, height) - SiSSetupSRCXY(src_x,src_y) - SiSSetupDSTXY(dst_x,dst_y) + SiSSetupSRCXY(src_x, src_y) + SiSSetupDSTXY(dst_x, dst_y) + SiSDoCMD } static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, - int color, int rop, unsigned int planemask) + int color, int rop, unsigned int planemask) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n", - color, rop, planemask)); + color, rop, planemask)); + if(pSiS->disablecolorkeycurrent) { + if((CARD32)color == pSiS->colorKey) { + rop = 5; /* NOOP */ + } + } SiSSetupPATFG(color) - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupROP(sisPatALUConv[rop]) - SiSSetupCMDFlag(X_INC | Y_INC | PATFG | BITBLT) + /* SiSSetupCMDFlag(PATFG) - is zero */ } static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, - int x, int y, int w, int h) + int x, int y, int w, int h) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long dstbase; PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n", - x, y, w, h)); + x, y, w, h)); + dstbase = 0; + if(y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) SiSSetupDSTXY(x,y) SiSSetupRect(w,h) + /* Clear commandReg because Setup can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + TRAPAZOID_FILL); + SiSSetupCMDFlag(X_INC | Y_INC | BITBLT) + SiSDoCMD } +/* TW: Trapezoid */ +/* This would work better if XAA would provide us with valid trapezoids. + * In fact, with small trapezoids the left and the right edge often cross + * each other or result in a line length of 0 which causes drawing errors + * (filling over whole scanline). + * Furthermore, I have not found out how to draw trapezoids with a height + * greater than 127. + */ +#ifdef TRAP +static void +SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR ) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; +#if 0 + float kL, kR; +#endif + + dstbase = 0; + if (y >= 2048) { + dstbase=pSiS->scrnOffset*y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) + /* SiSSetupRect(w,h) */ + +#if 1 + SiSSetupPATFG(0xff0000) /* FOR TESTING */ +#endif + + /* Clear CommandReg because SetUp can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + T_XISMAJORL | T_XISMAJORR | + BITBLT); + + xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n", + left, right, y, h, dxL, dyL, eL, dxR, dyR, eR); + + /* Unfortunately, we must check if the right and the left edge + * cross each other... INCOMPLETE (line equation wrong) + */ +#if 0 + if (dxL == 0) kL = 0; + else kL = (float)dyL / (float)dxL; + if (dxR == 0) kR = 0; + else kR = (float)dyR / (float)dxR; + xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR); + if ( (kR != kL) && + (!(kR == 0 && kL == 0)) && + (!(kR < 0 && kL > 0)) ) { + xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y); + if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) { + xf86DrvMsg(0, X_INFO, "Cross detected!\n"); + } + } +#endif + + /* Determine egde angles */ + if (dxL < 0) { dxL = -dxL; } + else { SiSSetupCMDFlag(T_L_X_INC) } + if (dxR < 0) { dxR = -dxR; } + else { SiSSetupCMDFlag(T_R_X_INC) } + + /* (Y direction always positive - do this anyway) */ + if (dyL < 0) { dyL = -dyL; } + else { SiSSetupCMDFlag(T_L_Y_INC) } + if (dyR < 0) { dyR = -dyR; } + else { SiSSetupCMDFlag(T_R_Y_INC) } + + /* Determine major axis */ + if (dxL >= dyL) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORL) + } + if (dxR >= dyR) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORR) + } + + /* Set up deltas */ + SiSSetupdL(dxL, dyL) + SiSSetupdR(dxR, dyR) + +#if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */ + h &= 0x7F; + if (h == 0) h = 10; +#endif + + /* Set up y, h, left, right */ + SiSSetupYH(y,h) + SiSSetupLR(left,right) + + /* Set up initial error term */ + SiSSetupEL(eL) + SiSSetupER(eR) + + SiSSetupCMDFlag(TRAPAZOID_FILL); + + SiSDoCMD +} +#endif + static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, - int color, int rop, unsigned int planemask) + int color, int rop, unsigned int planemask) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n", - color, rop, planemask)); + color, rop, planemask)); SiSSetupLineCount(1) SiSSetupPATFG(color) - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupROP(sisPatALUConv[rop]) SiSSetupCMDFlag(PATFG | LINE) } static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, - int x1, int y1, int x2, int y2, int flags) + int x1, int y1, int x2, int y2, int flags) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long dstbase,miny,maxy; PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n", - x1, y1, x2, y2, flags)); + x1, y1, x2, y2, flags)); + + dstbase = 0; + miny = (y1 > y2) ? y2 : y1; + maxy = (y1 > y2) ? y1 : y2; + if(maxy >= 2048) { + dstbase = pSiS->scrnOffset * miny; + y1 -= miny; + y2 -= miny; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) SiSSetupX0Y0(x1,y1) SiSSetupX1Y1(x2,y2) - if (flags & OMIT_LAST) + if (flags & OMIT_LAST) { SiSSetupCMDFlag(NO_LAST_PIXEL) + } else { + pSiS->CommandReg &= ~(NO_LAST_PIXEL); + } + SiSDoCMD } static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn, - int x, int y, int len, int dir) + int x, int y, int len, int dir) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long dstbase; PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n", - x, y, len, dir)); + x, y, len, dir)); + len--; /* starting point is included! */ + + dstbase = 0; + if((y >= 2048) || ((dir != DEGREES_0) && ((y + len) >= 2048))) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) SiSSetupX0Y0(x,y) - if (dir==DEGREES_0) - SiSSetupX1Y1(x+len,y) - else - SiSSetupX1Y1(x,y+len) + if (dir == DEGREES_0) { + SiSSetupX1Y1(x + len, y); + } else { + SiSSetupX1Y1(x, y + len); + } + SiSDoCMD } static void SiSSetupForDashedLine(ScrnInfoPtr pScrn, - int fg, int bg, int rop, unsigned int planemask, - int length, unsigned char *pattern) + int fg, int bg, int rop, unsigned int planemask, + int length, unsigned char *pattern) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n", - fg, bg, rop, planemask, length, *(pattern+4), *pattern)); + fg, bg, rop, planemask, length, *(pattern+4), *pattern)); SiSSetupLineCount(1) - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupStyleLow(*pattern) SiSSetupStyleHigh(*(pattern+4)) + SiSSetupStylePeriod(length-1); /* TW: This was missing!!! */ SiSSetupROP(sisPatALUConv[rop]) SiSSetupPATFG(fg) - if (bg != -1) SiSSetupPATBG(bg) + SiSSetupCMDFlag(LINE | LINE_STYLE) /* TW: This was missing!!! */ + if(bg != -1) { + SiSSetupPATBG(bg) + } else { + SiSSetupCMDFlag(TRANSPARENT); /* TW: This was missing!!! */ + } } static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, - int x1, int y1, int x2, int y2, - int flags, int phase) + int x1, int y1, int x2, int y2, + int flags, int phase) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long dstbase,miny,maxy; PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n", - x1, y1, x2, y2, flags, phase)); + x1, y1, x2, y2, flags, phase)); + + dstbase = 0; + miny = (y1 > y2) ? y2 : y1; + maxy = (y1 > y2) ? y1 : y2; + if(maxy >= 2048) { + dstbase = pSiS->scrnOffset * miny; + y1 -= miny; + y2 -= miny; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) SiSSetupX0Y0(x1,y1) SiSSetupX1Y1(x2,y2) - if (flags & OMIT_LAST) + if(flags & OMIT_LAST) { SiSSetupCMDFlag(NO_LAST_PIXEL) + } else { + pSiS->CommandReg &= ~(NO_LAST_PIXEL); + } + SiSDoCMD } + static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, int fg, int bg, - int rop, unsigned int planemask) + int patx, int paty, int fg, int bg, + int rop, unsigned int planemask) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n", - patx, paty, fg, bg, rop, planemask)); - - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ + patx, paty, fg, bg, rop, planemask)); SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupMONOPAT(patx,paty) SiSSetupPATFG(fg) SiSSetupROP(sisPatALUConv[rop]) - SiSSetupCMDFlag(PATMONO | X_INC | Y_INC) -/* if (bg==-1) - SiSSetupCMDFlag(TRANSPARENT) - else*/ - SiSSetupPATBG(bg) + SiSSetupCMDFlag(PATMONO) + SiSSetupPATBG(bg) } static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, - int x, int y, int w, int h) + int patx, int paty, + int x, int y, int w, int h) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long dstbase; PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n", - patx, paty, x, y, w, h)); - SiSSetupDSTXY(x,y) - SiSSetupRect(w,h) + patx, paty, x, y, w, h)); + dstbase = 0; + + if(y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) + SiSSetupDSTXY(x, y) + SiSSetupRect(w, h) + /* Clear commandReg because Setup can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + TRAPAZOID_FILL); + SiSSetupCMDFlag(X_INC | Y_INC) + + SiSDoCMD +} + +/* Trapezoid */ +#ifdef TRAP +static void +SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, + int patx, int paty, + int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR ) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; + + PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n", + y, h, left, right, dxL, dxR, eL, eR)); + + dstbase = 0; + if(y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) + + /* Clear CommandReg because SetUp can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + BITBLT); + + if (dxL < 0) { dxL = -dxL; } + else { SiSSetupCMDFlag(T_L_X_INC) } + if (dxR < 0) { dxR = -dxR; } + else { SiSSetupCMDFlag(T_R_X_INC) } + + if (dyL < 0) { dyL = -dyL; } + else { SiSSetupCMDFlag(T_L_Y_INC) } + if (dyR < 0) { dyR = -dyR; } + else { SiSSetupCMDFlag(T_R_Y_INC) } + + /* Determine major axis */ + if (dxL >= dyL) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORL) + } + if (dxR >= dyR) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORR) + } + + SiSSetupYH(y,h) + SiSSetupLR(left,right) + + SiSSetupdL(dxL, dyL) + SiSSetupdR(dxR, dyR) + + SiSSetupEL(eL) + SiSSetupER(eR) + + SiSSetupCMDFlag(TRAPAZOID_FILL); + SiSDoCMD } +#endif + + +#if 0 + +/* TW: The following (already commented) functions have NOT been adapted for dual-head mode */ + + +/* ------- Color Pattern Fill --- is not useful for XAA -------------- */ static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, int rop, - unsigned int planemask, - int trans_color) + int patx, int paty, int rop, + unsigned int planemask, + int trans_color) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup ColorPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x)\n", - patx, paty, rop, planemask, trans_color)); + patx, paty, rop, planemask, trans_color)); - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ +/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupROP(sisPatALUConv[rop]) SiSSetupCMDFlag(PATPATREG | X_INC | Y_INC) } static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn, - int patx, int paty, - int x, int y, int w, int h) + int patx, int paty, + int x, int y, int w, int h) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long dstbase; PDEBUG(ErrorF("Subsequent ColorPatFill(0x%x,0x%x, %d,%d, %d,%d)\n", - patx, paty, x, y, w, h)); + patx, paty, x, y, w, h)); + + dstbase = 0; + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } + SiSSetupDSTBase(dstbase) SiSSetupDSTXY(x,y) SiSSetupRect(w,h) SiSDoCMD } +/* ----- CPU To Screen Color Expand (single task) ------------------------- */ + +/* This does not work. Assumingly for the same + * reason why STSColorExpand does not work either. + */ static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, - int fg, int bg, - int rop, unsigned int planemask) + int fg, int bg, + int rop, unsigned int planemask) { - SISPtr pSiS = SISPTR(pScrn); - XAAInfoRecPtr pXAA = XAAPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup CPUToScreen ColorExpand(0x%x,0x%x, 0x%x,0x%x)\n", - fg, bg, rop, planemask)); + fg, bg, rop, planemask)); - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ +/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupSRCXY(0,0) SiSSetupSRCFG(fg) SiSSetupROP(sisPatALUConv[rop]) SiSSetupCMDFlag(X_INC | Y_INC | COLOREXP) - if (bg==-1) + if (bg == -1) { SiSSetupCMDFlag(TRANSPARENT) - else + } + else { SiSSetupSRCBG(bg) + } } static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn, - int x, int y, int w, int h, int skipleft) + int x, int y, int w, int h, int skipleft) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long dstbase; PDEBUG(ErrorF("Subsequent CPUToScreen ColorExpand(%d,%d, %d,%d, %d)\n", - x, y, w, h, skipleft)); + x, y, w, h, skipleft)); + + dstbase = 0; + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } + SiSSetupDSTBase(dstbase) -/* SiSSetupSRCPitch(((w+31)&0xFFE0)/8)*/ +/* SiSSetupSRCPitch(((w+31)&0xFFE0)/8)*/ SiSSetupSRCPitch((w+7)/8) SiSSetupDSTXY(x,y) SiSSetupRect(w,h) -/* SiSDoCMD*/ +/* SiSDoCMD*/ pSiS->DoColorExpand = TRUE; } +#endif + +/* ------ Screen To Screen Color Expand ------------------------------- */ +/* TW: The hareware does not seem to support this the way we need it */ + +#ifdef STSCE static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, - int fg, int bg, - int rop, unsigned int planemask) + int fg, int bg, + int rop, unsigned int planemask) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); PDEBUG(ErrorF("Setup ScreenToScreen ColorExp(0x%x,0x%x, 0x%x)\n", - fg, bg, rop)); + fg, bg, rop)); - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ + SiSSetupDSTColorDepth(pSiS->DstColor) SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); - SiSSetupSRCFG(fg) - SiSSetupSRCBG(bg) - SiSSetupSRCXY(0,0) SiSSetupROP(sisALUConv[rop]) - SiSSetupCMDFlag(X_INC | Y_INC | ENCOLOREXP) + SiSSetupSRCFG(fg) + /* SiSSetupSRCXY(0,0) */ + + if(bg == -1) { + SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | X_INC | + Y_INC | SRCVIDEO); + } else { + SiSSetupSRCBG(bg); + SiSSetupCMDFlag(ENCOLOREXP | X_INC | Y_INC | + SRCVIDEO); + }; } +#endif + +/* TW. This method blits in a single task; this does not seem to work + * because the hardware does not use the source pitch as scanline + * offset but only to calculate pattern address from source X and Y. + * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8) + * offset, but this does not seem to be supported by the hardware. + */ +#ifdef STSCE + +/* For testing, these are the methods: (use only one at a time!) */ + +#undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch + * This would work if the hareware used the source pitch for + * incrementing the source address after each scanline - but + * it doesn't do this! The first line of the area is correctly + * color expanded, but since the source pitch is ignored and + * the source address not incremented correctly, the following + * lines are color expanded with any bit pattern that is left + * in the unused space of the source bitmap (which is organized + * with the depth of the screen framebuffer hence with a pitch + * of scrnOffset). + */ + +#undef pitchdw /* Use source pitch "displayWidth / 8" instead + * of scrnOffset (=displayWidth * bpp / 8) + * This can't work, because the pitch of the source + * bitmap is scrnoffset! + */ + +#define nopitch /* Calculate srcbase with srcx and srcy, set the + * pitch to scrnOffset (which IS the correct pitch + * for the source bitmap) and set srcx and srcy both + * to 0. + * This would work if the hareware used the source pitch for + * incrementing the source address after each scanline - but + * it doesn't do this! Again: The first line of the area is + * correctly color expanded, but since the source pitch is + * ignored for scanline address incremention, the following + * lines are not correctly color expanded. + * WHATEVER I write to source pitch is ignored! + */ static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, - int x, int y, int w, int h, - int srcx, int srcy, int skipleft) + int x, int y, int w, int h, + int srcx, int srcy, int skipleft) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long srcbase, dstbase; +#if 0 + int _x0, _y0, _x1, _y1; +#endif +#ifdef pitchdw + int newsrcx, newsrcy; + + /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 ) + * We recalulate srcx and srcy based on pitch = displayWidth / 8 + */ + newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) / + (pScrn->displayWidth/8); + newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) % + (pScrn->displayWidth/8); +#endif + xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n", + x, y, w, h, srcx, srcy, skipleft); - PDEBUG(ErrorF("Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n", - x, y, w, h, srcx, srcy, skipleft)); + srcbase = dstbase = 0; + +#ifdef pitchdw + if (newsrcy >= 2048) { + srcbase = (pScrn->displayWidth / 8) * newsrcy; + newsrcy = 0; + } +#endif +#ifdef nopitch + srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8)); +#endif +#ifdef npitch + if (srcy >= 2048) { + srcbase = pSiS->scrnOffset * srcy; + srcy = 0; + } +#endif + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; + } +#endif + SiSSetupSRCBase(srcbase) + SiSSetupDSTBase(dstbase) + +#ifdef pitchdw + SiSSetupSRCPitch(pScrn->displayWidth/8) +#endif +#ifdef nopitch + SiSSetupSRCPitch(pSiS->scrnOffset) + /* SiSSetupSRCPitch(100) */ /* For test - has NO effect WHATSOEVER */ +#endif +#ifdef npitch + SiSSetupSRCPitch(pSiS->scrnOffset) +#endif - SiSSetupSRCPitch(((w+31)&0xFFE0)/8) - SiSSetupDSTXY(x,y) SiSSetupRect(w,h) + +#if 0 /* How do I implement the offset? Not this way, that's for sure.. */ + if (skipleft > 0) { + _x0 = x+skipleft; + _y0 = y; + _x1 = x+w; + _y1 = y+h; + SiSSetupClipLT(_x0, _y0); + SiSSetupClipRB(_x1, _y1); + SiSSetupCMDFlag(CLIPENABLE); + } +#endif +#ifdef pitchdw + SiSSetupSRCXY(newsrcx, newsrcy) +#endif +#ifdef nopitch + SiSSetupSRCXY(0,0) +#endif +#ifdef npitch + SiSSetupSRCXY(srcx, srcy) +#endif + + SiSSetupDSTXY(x,y) + SiSDoCMD } +#endif +/* TW: TEST: Do it scanline-wise because the other way does not seem to + * be supported by the hardware. (The source pitch seems to be + * displayWidth * (bbp/8) as opposed by the XAA HOWTO, where + * it is stated that the pitch would be displayWidth pixels; + * besides, the hardware seems to ignore the source pitch + * for address increments.) + * Apart from this (which can be solved by doing the color + * expand scanline-wise), I don't know how to implement the + * offset argument. The current method (which uses hardware + * clipping) does not work. + * + * THIS DOES NOT WORK IN THE CURRENT STATE. + */ +#if 0 +static void +SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int srcx, int srcy, int offset) +{ + SISPtr pSiS = SISPTR(pScrn); + long srcbase, dstbase; + int _x0, _y0, _x1, _y1; + + int newsrcx, newsrcy; + + newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) / + (((((w+7)/8)+3) >> 2) * 4); + /* (pScrn->displayWidth/8); */ + newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) % + (((((w+7)/8)+3) >> 2) * 4); + /* (pScrn->displayWidth/8); */ + + xf86DrvMsg(0, X_INFO, "Sub STS CE(%d,%d, %d,%d, %d,%d, %d)\n", + x, y, w, h, srcx, srcy, skipleft); + + srcbase = dstbase = 0; + if (newsrcy >= 2048) { + srcbase = (((((w+7)/8)+3) >> 2) * 4) * newsrcy; + /* (pScrn->displayWidth/8) * newsrcy; */ + /* pSiS->scrnOffset * srcy; */ + newsrcy = 0; + } + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + SiSSetupRect(w, 1) + SiSSetupSRCXY(newsrcx, newsrcy) + + /* SiSSetupSRCPitch(pScrn->displayWidth/8) */ /* old: (((w+31)&0xFFE0)/8) */ + SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4) +#if 1 + if (offset > 0) { + SiSSetupCMDFlag(CLIPENABLE) + } else + pSiS->CommandReg &= ~CLIPENABLE; +#endif + + while (h) { + + SiSSetupSRCBase(srcbase) +#if 1 + if (offset > 0) { + _x0 = x+skipleft; + _y0 = y; + _x1 = x+w; + _y1 = y+h; + SiSSetupClipLT(_x0, _y0); + SiSSetupClipRB(_x1, _y1); + } +#endif + SiSSetupDSTXY(x,y) + SiSDoCMD + + srcbase += ((((w+7)/8)+3) >> 2) * 4 * 8* ((pScrn->bitsPerPixel+7)/8); + /* pSiS->scrnOffset; */ + y++; + h--; + } +} +#endif + + +/* ----- CPU To Screen Color Expand (scanline-wise) ----------------- */ + +/* We do it using the indirect method */ -#ifdef DEBUG static void -MMIODump(ScrnInfoPtr pScrn) +SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask) { - SISPtr pSiS = SISPTR(pScrn); - int i; + SISPtr pSiS=SISPTR(pScrn); - SiSIdle - for (i=0x8200; i<0x8250; i+=16) { - ErrorF("MMIO %x: %0X %0X %0X %0X\n", i, - MMIO_IN32(pSiS->IOBase, i ), - MMIO_IN32(pSiS->IOBase, i+ 4), - MMIO_IN32(pSiS->IOBase, i+ 8), - MMIO_IN32(pSiS->IOBase, i+12)); + /* TW: Make sure that current CPU-driven BitBlt buffer stage is 0 + * This is required!!! (Otherwise -> drawing errors) + */ + while((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x1F00) != 0) {} /* WDR: == 0x10 */ + +#if 0 /* TW: This is obviously not needed */ + pSiS->ColorExpandRingHead = 0; + pSiS->ColorExpandRingTail = pSiS->ColorExpandBufferNumber - 1; +#endif + + SiSSetupSRCXY(0,0); + SiSSetupROP(sisALUConv[rop]); + SiSSetupSRCFG(fg); + SiSSetupDSTRect(pSiS->scrnOffset, -1); + SiSSetupDSTColorDepth(pSiS->DstColor); + if(bg == -1) { + SiSSetupCMDFlag(TRANSPARENT | + ENCOLOREXP | + X_INC | Y_INC | + SRCCPUBLITBUF); + } else { + SiSSetupSRCBG(bg); + SiSSetupCMDFlag(ENCOLOREXP | + X_INC | Y_INC | + SRCCPUBLITBUF); + } +} + + +static void +SiSSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, int y, int w, + int h, int skipleft) +{ + SISPtr pSiS = SISPTR(pScrn); + int _x0, _y0, _x1, _y1; + long dstbase; + + dstbase = 0; + if((y >= 2048) || ((y + h) >= 2048)) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + + /* TW: Wait until there is no color expansion command in queue + * (This solves the OpenOffice.org window-move bug) + * Added Idle-check - bit 23 is set sometimes, although + * engine is actually idle! + * Update: Bit 23 is not reliable. After heavy 3D engine + * action, this bit never gets cleared again. So do + * SiSIdle instead. + */ + if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) { + /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */ + SiSIdle + } + + SiSSetupDSTBase(dstbase) + + if (skipleft > 0) { + _x0 = x + skipleft; + _y0 = y; + _x1 = x + w; + _y1 = y + h; + SiSSetupClipLT(_x0, _y0); + SiSSetupClipRB(_x1, _y1); + SiSSetupCMDFlag(CLIPENABLE); + } else { + pSiS->CommandReg &= (~CLIPENABLE); } + + SiSSetupRect(w, 1); + SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4); + pSiS->xcurrent = x; + pSiS->ycurrent = y; } + +static void +SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + SISPtr pSiS=SISPTR(pScrn); +#if 0 + int newhead,bltbufstage,newtail; +#endif + long cbo; + + cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + cbo += HEADOFFSET; + } #endif + + /* TW: Wait until there is no color expansion command in queue + * (This solves the GTK-big-font bug) + * Added Idle-check - bit 23 is set sometimes, although + * engine is actually idle! + * Update: Bit 23 is not reliable. After heavy 3D engine + * action, this bit never gets cleared again. So do + * SiSIdle instead. + */ + if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) { + /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */ + SiSIdle + } + + SiSSetupSRCBase(cbo); + + SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent); + + SiSDoCMD + + pSiS->ycurrent++; + + if(pSiS->VGAEngine == SIS_530_VGA) { + while(MMIO_IN8(pSiS->IOBase, 0x8242) & 0x80) {} + } + +#if 0 /* TW: What is this good for? The Head/Tail data is never ever used elsewhere! */ + pSiS->ColorExpandRingHead = newhead = + (bufno + 1) & pSiS->ColorExpandBufferCountMask; + while (newhead == pSiS->ColorExpandRingTail) { + bltbufstage = (int)((MMIO_IN16(pSiS->IOBase,0x8242) & 0x1F00) >> 8); + newtail = newhead - (bltbufstage + 1); + pSiS->ColorExpandRingTail = (newtail >= 0) ? + newtail : (pSiS->ColorExpandBufferNumber + newtail); + } +#endif +} + + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.h index 0d6293801..308da24b7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.h @@ -1,160 +1,1181 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.h,v 1.12 2003/06/28 14:03:13 twini Exp $ */ /* - * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * 2D Acceleration for SiS300, SiS540, SiS630, SiS730, SiS530, SiS620 + * Definitions for the SIS engine communication + * + * Copyright Xavier Ducoin <x.ducoin@lectra.com> + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. - * Xavier Ducoin <x.ducoin@lectra.com> + * Authors: + * + * Xavier Ducoin <x.ducoin@lectra.com> + * Thomas Winischhofer <thomas@winischhofer.net> + * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.h,v 1.1 2000/02/12 20:45:32 dawes Exp $ */ +#define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */ +#define BR(x) (0x8200 | (x) << 2) +#define PBR(x) (0x8300 | (x) << 2) -/* Definitions for the SIS engine communication. */ +/* SiS300 engine commands */ +#define BITBLT 0x00000000 /* Blit */ +#define COLOREXP 0x00000001 /* Color expand */ +#define ENCOLOREXP 0x00000002 /* Enhanced color expand */ +#define MULTIPLE_SCANLINE 0x00000003 /* ? */ +#define LINE 0x00000004 /* Draw line */ +#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */ +#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */ -#define PATREGSIZE 384 -#define BR(x) (0x8200 | (x) << 2) -#define PBR(x) (0x8300 | (x) << 2) +/* source select */ +#define SRCVIDEO 0x00000000 /* source is video RAM */ +#define SRCSYSTEM 0x00000010 /* source is system memory */ +#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */ +#define SRCAGP 0x00000020 /* source is AGP memory (?) */ -/* Definitions for the SiS300 engine command */ -#define BITBLT 0x00000000 -#define COLOREXP 0x00000001 -#define ENCOLOREXP 0x00000002 -#define MULTIPLE_SCANLINE 0x00000003 -#define LINE 0x00000004 -#define TRAPAZOID_FILL 0x00000005 -#define TRANSPARENT_BITBLT 0x00000006 - -#define SRCVIDEO 0x00000000 -#define SRCSYSTEM 0x00000010 -#define SRCAGP 0x00000020 - -#define PATFG 0x00000000 -#define PATPATREG 0x00000040 -#define PATMONO 0x00000080 +/* Pattern flags */ +#define PATFG 0x00000000 /* foreground color */ +#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */ +#define PATMONO 0x00000080 /* mono pattern */ +/* blitting direction */ #define X_INC 0x00010000 #define X_DEC 0x00000000 #define Y_INC 0x00020000 #define Y_DEC 0x00000000 -#define NOCLIP 0x00000000 -#define NOMERGECLIP 0x04000000 -#define CLIPENABLE 0x00040000 -#define CLIPWITHOUTMERGE 0x04040000 +/* Clipping flags */ +#define NOCLIP 0x00000000 +#define NOMERGECLIP 0x04000000 +#define CLIPENABLE 0x00040000 +#define CLIPWITHOUTMERGE 0x04040000 +/* Transparency */ #define OPAQUE 0x00000000 -#define TRANSPARENT 0x00100000 +#define TRANSPARENT 0x00100000 + +/* Trapezoid */ +#define T_XISMAJORL 0x00800000 /* X axis is driving axis (left) */ +#define T_XISMAJORR 0x01000000 /* X axis is driving axis (right) */ +#define T_L_Y_INC Y_INC /* left edge direction Y */ +#define T_L_X_INC X_INC /* left edge direction X */ +#define T_R_Y_INC 0x00400000 /* right edge direction Y */ +#define T_R_X_INC 0x00200000 /* right edge direction X */ -#define DSTAGP 0x02000000 +/* ? */ +#define DSTAGP 0x02000000 #define DSTVIDEO 0x02000000 /* Line */ -#define LINE_STYLE 0x00800000 -#define NO_RESET_COUNTER 0x00400000 -#define NO_LAST_PIXEL 0x00200000 +#define LINE_STYLE 0x00800000 +#define NO_RESET_COUNTER 0x00400000 +#define NO_LAST_PIXEL 0x00200000 + /* Macros to do useful things with the SIS BitBLT engine */ -/* +/* BR(16) (0x8240): + bit 31 2D engine: 1 is idle, bit 30 3D engine: 1 is idle, bit 29 Command queue: 1 is empty + + bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0] + + bits 15:0: Current command queue length (530/620: 12:0) + */ +/* TW: BR(16)+2 = 0x8242 */ + +#define CmdQueLen pSiS->cmdQueueLen + #define SiSIdle \ - while( (MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; + { \ + while( (MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ + while( (MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ + while( (MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ + CmdQueLen = (MMIO_IN16(pSiS->IOBase, 0x8240) & pSiS->CmdQueLenMask) - pSiS->CmdQueLenFix; \ + } +/* TW: (do three times, because 2D engine seems quite unsure about whether or not it's idle) */ #define SiSSetupSRCBase(base) \ - MMIO_OUT32(pSiS->IOBase, BR(0), base); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(0), base);\ + CmdQueLen--; #define SiSSetupSRCPitch(pitch) \ - MMIO_OUT16(pSiS->IOBase, BR(1), pitch); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, BR(1), pitch);\ + CmdQueLen--; #define SiSSetupSRCXY(x,y) \ - MMIO_OUT32(pSiS->IOBase, BR(2), (x)<<16 | (y) ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(2), (x)<<16 | (y) );\ + CmdQueLen--; #define SiSSetupDSTBase(base) \ - MMIO_OUT32(pSiS->IOBase, BR(4), base); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(4), base);\ + CmdQueLen--; #define SiSSetupDSTXY(x,y) \ - MMIO_OUT32(pSiS->IOBase, BR(3), (x)<<16 | (y) ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(3), (x)<<16 | (y) );\ + CmdQueLen--; #define SiSSetupDSTRect(x,y) \ - MMIO_OUT32(pSiS->IOBase, BR(5), (y)<<16 | (x) ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(5), (y)<<16 | (x) );\ + CmdQueLen--; #define SiSSetupDSTColorDepth(bpp) \ - MMIO_OUT16(pSiS->IOBase, BR(1)+2, bpp); + if(pSiS->VGAEngine != SIS_530_VGA) { \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, BR(1)+2, bpp);\ + CmdQueLen--; \ + } #define SiSSetupRect(w,h) \ - MMIO_OUT32(pSiS->IOBase, BR(6), (h)<<16 | (w) ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(6), (h)<<16 | (w) );\ + CmdQueLen--; #define SiSSetupPATFG(color) \ - MMIO_OUT32(pSiS->IOBase, BR(7), color); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(7), color);\ + CmdQueLen--; #define SiSSetupPATBG(color) \ - MMIO_OUT32(pSiS->IOBase, BR(8), color); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(8), color);\ + CmdQueLen--; #define SiSSetupSRCFG(color) \ - MMIO_OUT32(pSiS->IOBase, BR(9), color); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(9), color);\ + CmdQueLen--; #define SiSSetupSRCBG(color) \ - MMIO_OUT32(pSiS->IOBase, BR(10), color); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(10), color);\ + CmdQueLen--; + +/* 0x8224 src colorkey high */ +/* 0x8228 src colorkey low */ +/* 0x821c dest colorkey high */ +/* 0x8220 dest colorkey low */ +#define SiSSetupSRCTrans(color) \ + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x8224, color);\ + MMIO_OUT32(pSiS->IOBase, 0x8228, color);\ + CmdQueLen -= 2; + +#define SiSSetupDSTTrans(color) \ + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x821C, color); \ + MMIO_OUT32(pSiS->IOBase, 0x8220, color); \ + CmdQueLen -= 2; #define SiSSetupMONOPAT(p0,p1) \ - MMIO_OUT32(pSiS->IOBase, BR(11), p0); \ - MMIO_OUT32(pSiS->IOBase, BR(12), p1); + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(11), p0);\ + MMIO_OUT32(pSiS->IOBase, BR(12), p1);\ + CmdQueLen -= 2; #define SiSSetupClipLT(left,top) \ - MMIO_OUT32(pSiS->IOBase, BR(13), ((left) & 0xFFFF) | (top)<<16 ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\ + CmdQueLen--; #define SiSSetupClipRB(right,bottom) \ - MMIO_OUT32(pSiS->IOBase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\ + CmdQueLen--; +/* General */ #define SiSSetupROP(rop) \ - pSiS->CommandReg = (rop) << 8; + pSiS->CommandReg = (rop) << 8; #define SiSSetupCMDFlag(flags) \ - pSiS->CommandReg |= (flags); + pSiS->CommandReg |= (flags); #define SiSDoCMD \ - MMIO_OUT32(pSiS->IOBase, BR(15), pSiS->CommandReg); \ - MMIO_OUT32(pSiS->IOBase, BR(16), 0); + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(15), pSiS->CommandReg); \ + CmdQueLen--; \ + if(pSiS->VGAEngine != SIS_530_VGA) { \ + MMIO_OUT32(pSiS->IOBase, BR(16), 0);\ + CmdQueLen--; \ + } else { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, BR(16)); \ + } \ +/* Line */ #define SiSSetupX0Y0(x,y) \ - MMIO_OUT32(pSiS->IOBase, BR(2), (y)<<16 | (x) ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(2), (y)<<16 | (x) );\ + CmdQueLen--; #define SiSSetupX1Y1(x,y) \ - MMIO_OUT32(pSiS->IOBase, BR(3), (y)<<16 | (x) ); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(3), (y)<<16 | (x) );\ + CmdQueLen--; #define SiSSetupLineCount(c) \ - MMIO_OUT16(pSiS->IOBase, BR(6), c); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, BR(6), c);\ + CmdQueLen--; #define SiSSetupStylePeriod(p) \ - MMIO_OUT16(pSiS->IOBase, BR(6)+2, p); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, BR(6)+2, p);\ + CmdQueLen--; #define SiSSetupStyleLow(ls) \ - MMIO_OUT32(pSiS->IOBase, BR(11), ls); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(11), ls);\ + CmdQueLen--; #define SiSSetupStyleHigh(ls) \ - MMIO_OUT32(pSiS->IOBase, BR(12), ls); + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, BR(12), ls);\ + CmdQueLen--; + +/* TW: Trapezoid */ +#define SiSSetupYH(y,h) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x8208, (y)<<16 | (h) );\ + CmdQueLen--; + +#define SiSSetupLR(left,right) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x820C, (right)<<16 | (left) );\ + CmdQueLen--; + +#define SiSSetupdL(dxL,dyL) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x8244, (dyL)<<16 | (dxL) );\ + CmdQueLen--; + +#define SiSSetupdR(dxR,dyR) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x8248, (dyR)<<16 | (dxR) );\ + CmdQueLen--; + +#define SiSSetupEL(eL) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x824C, eL);\ + CmdQueLen--; + +#define SiSSetupER(eR) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, 0x8250, eR);\ + CmdQueLen--; + + +/* Set Pattern register */ +#define SiSSetPattern(num, value) \ + if (CmdQueLen <= 0) SiSIdle; \ + MMIO_OUT32(pSiS->IOBase, (PATTERN_REG + (num * 4)), value); \ + CmdQueLen--; + + +/* 3D stuff (used for RENDER) */ + +/* + * Register Addresses of 300/630/730/(540?) + */ +#define REG_3D_TSFSa 0x8800 +#define REG_3D_TSZa 0x8804 +#define REG_3D_TSXa 0x8808 +#define REG_3D_TSYa 0x880C +#define REG_3D_TSARGBa 0x8810 +#define REG_3D_TSWGa 0x8814 +#define REG_3D_TSUAa 0x8818 +#define REG_3D_TSVAa 0x881C +#define REG_3D_TSUBa 0x8820 +#define REG_3D_TSVBa 0x8824 +#define REG_3D_TSUCa 0x8828 +#define REG_3D_TSVCa 0x882C + +#define REG_3D_TSFSb 0x8830 +#define REG_3D_TSZb 0x8834 +#define REG_3D_TSXb 0x8838 +#define REG_3D_TSYb 0x883C +#define REG_3D_TSARGBb 0x8840 +#define REG_3D_TSWGb 0x8844 +#define REG_3D_TSUAb 0x8848 +#define REG_3D_TSVAb 0x884C +#define REG_3D_TSUBb 0x8850 +#define REG_3D_TSVBb 0x8854 +#define REG_3D_TSUCb 0x8858 +#define REG_3D_TSVCb 0x885C + +#define REG_3D_TSFSc 0x8860 +#define REG_3D_TSZc 0x8864 +#define REG_3D_TSXc 0x8868 +#define REG_3D_TSYc 0x886C +#define REG_3D_TSARGBc 0x8870 +#define REG_3D_TSWGc 0x8874 +#define REG_3D_TSUAc 0x8878 +#define REG_3D_TSVAc 0x887C +#define REG_3D_TSUBc 0x8880 +#define REG_3D_TSVBc 0x8884 +#define REG_3D_TSUCc 0x8888 +#define REG_3D_TSVCc 0x888C + +/* + * REG_3D_AGPCmdSetting (89e4h-89f7) + */ +#define REG_3D_AGPCmBase 0x89E4 +#define REG_3D_AGPRmDwNum 0x89E8 +#define REG_3D_AGPTtDwNum 0x89EC +#define REG_3D_AGPCmFire 0x89F0 + +#define REG_3D_ParsingSet 0x89F4 +#define REG_3D_PrimitiveSet 0x89F8 +#define REG_3D_ShadeMode 0x89F8 +#define REG_3D_EngineFire 0x89FC +#define REG_3D_EngineStatus 0x89FC +#define REG_3D_TEnable 0x8A00 +#define REG_3D_TEnable2 0x8A04 + +#define REG_3D_ZSet 0x8A08 +#define REG_3D_ZBias 0x8A0C +#define REG_3D_ZStWriteMask 0x8A10 + +#define REG_3D_ZAddress 0x8A14 +#define REG_3D_AlphaSet 0x8A18 +#define REG_3D_AlphaAddress 0x8A1C +#define REG_3D_DstSet 0x8A20 +#define REG_3D_DstAlphaWriteMask 0x8A24 + +#define REG_3D_DstAddress 0x8A28 + +#define REG_3D_LinePattern 0x8A2C + +#define REG_3D_FogSet 0x8A30 + +#define REG_3D_FogFarDistance 0x8A34 +#define REG_3D_FogInverseDistance 0x8A38 +#define REG_3D_FogFactorDensity 0x8A3C + +#define REG_3D_StencilSet 0x8A44 +#define REG_3D_StencilSet2 0x8A48 +#define REG_3D_StencilAddress 0x8A4C + +#define REG_3D_DstBlendMode 0x8A50 +#define REG_3D_SrcBlendMode 0x8A50 +#define REG_3D_ClipTopBottom 0x8A54 +#define REG_3D_ClipLeftRight 0x8A58 + +#define REG_3D_Brightness 0x8A5C + +#define REG_3D_BumpMapSet 0x8A68 +#define REG_3D_BumpMapAddress 0x8A6C +#define REG_3D_BumpMapPitch 0x8A70 +#define REG_3D_BumpMapMatrix0 0x8A74 +#define REG_3D_BumpMapMatrix1 0x8A78 + +/* + * Texture Registers + */ +#define REG_3D_TextureSet 0x8A7C +#define REG_3D_TextureWidthHeight 0x8A7C +#define REG_3D_TextureMip 0x8A80 + +#define REG_3D_TextureTransparencyColorHigh 0x8A84 +#define REG_3D_TextureTransparencyColorLow 0x8A88 +#define REG_3D_TextureBorderColor 0x8A8C +#define REG_3D_TextureAddress0 0x8A90 +#define REG_3D_TextureAddress1 0x8A94 +#define REG_3D_TextureAddress2 0x8A98 +#define REG_3D_TextureAddress3 0x8A9C +#define REG_3D_TextureAddress4 0x8AA0 +#define REG_3D_TextureAddress5 0x8AA4 +#define REG_3D_TextureAddress6 0x8AA8 +#define REG_3D_TextureAddress7 0x8AAC +#define REG_3D_TextureAddress8 0x8AB0 +#define REG_3D_TextureAddress9 0x8AB4 +#define REG_3D_TextureAddress10 0x8AB8 +#define REG_3D_TextureAddress11 0x8ABC +#define REG_3D_TexturePitch0 0x8AC0 +#define REG_3D_TexturePitch1 0x8AC0 +#define REG_3D_TexturePitch2 0x8AC4 +#define REG_3D_TexturePitch3 0x8AC4 +#define REG_3D_TexturePitch4 0x8AC8 +#define REG_3D_TexturePitch5 0x8AC8 +#define REG_3D_TexturePitch6 0x8ACC +#define REG_3D_TexturePitch7 0x8ACC +#define REG_3D_TexturePitch8 0x8AD0 +#define REG_3D_TexturePitch9 0x8AD0 +#define REG_3D_TexturePitch10 0x8AD4 + +#define REG_3D_Texture1Set 0x8ADC +#define REG_3D_Texture1WidthHeight 0x8ADC +#define REG_3D_Texture1Mip 0x8AE0 + +#define REG_3D_Texture1TransparencyColorHigh 0x8AE4 +#define REG_3D_Texture1TransparencyColorLow 0x8AE8 +#define REG_3D_Texture1BorderColor 0x8AEC +#define REG_3D_Texture1Address0 0x8AF0 +#define REG_3D_Texture1Address1 0x8AF4 +#define REG_3D_Texture1Address2 0x8AF8 +#define REG_3D_Texture1Address3 0x8AFC +#define REG_3D_Texture1Address4 0x8B00 +#define REG_3D_Texture1Address5 0x8B04 +#define REG_3D_Texture1Address6 0x8B08 +#define REG_3D_Texture1Address7 0x8B0C +#define REG_3D_Texture1Address8 0x8B10 +#define REG_3D_Texture1Address9 0x8B14 +#define REG_3D_Texture1Address10 0x8B18 +#define REG_3D_Texture1Address11 0x8B1C +#define REG_3D_Texture1Pitch0 0x8B20 +#define REG_3D_Texture1Pitch1 0x8B20 +#define REG_3D_Texture1Pitch2 0x8B24 +#define REG_3D_Texture1Pitch3 0x8B24 +#define REG_3D_Texture1Pitch4 0x8B28 +#define REG_3D_Texture1Pitch5 0x8B28 +#define REG_3D_Texture1Pitch6 0x8B2C +#define REG_3D_Texture1Pitch7 0x8B2C +#define REG_3D_Texture1Pitch8 0x8B30 +#define REG_3D_Texture1Pitch9 0x8B30 +#define REG_3D_Texture1Pitch10 0x8B34 + +#define REG_3D_TextureBlendFactor 0x8B3C +#define REG_3D_TextureColorBlendSet0 0x8B40 +#define REG_3D_TextureColorBlendSet1 0x8B44 +#define REG_3D_TextureAlphaBlendSet0 0x8B48 +#define REG_3D_TextureAlphaBlendSet1 0x8B4C + +#define REG_3D_EndPrimitiveList 0x8B50 + +#define REG_3D_Stipple0 0x8B60 + +#define REG_3D_TexturePalette 0x8C00 + +/* + * REG_3D_ParsingSet - Parsing Mask (89F4h-89F7h) + */ +#define MASK_VertexDWSize 0xF0000000 +#define MASK_VertexDataFormat 0x0FFF0000 +#define MASK_PsVertex_HAS_RHW 0x08000000 +#define MASK_PsVertex_HAS_NORMALXYZ 0x04000000 +#define MASK_PsVertex_HAS_DIFFUSE 0x02000000 +#define MASK_PsVertex_HAS_SPECULAR 0x01000000 +#define MASK_PsUVSet 0x00FF0000 +#define MASK_PsVertex_HAS_1SetUV 0x00800000 +#define MASK_PsVertex_HAS_2SetUV 0x00C00000 +#define MASK_PsVertex_HAS_3SetUV 0x00E00000 +#define MASK_PsVertex_HAS_UVSet1 0x00800000 +#define MASK_PsVertex_HAS_UVSet2 0x00400000 +#define MASK_PsVertex_HAS_UVSet3 0x00200000 +#define MASK_PsCullDirection_CCW 0x00008000 +#define MASK_PsShadingMode 0x00007000 +#define MASK_PsTextureFrom 0x000003F0 +#define MASK_PsTexture0FromA 0x00000000 +#define MASK_PsTexture1FromA 0x00000000 +#define MASK_PsTexture1FromB 0x00000040 +#define MASK_PsBumpTextureFromA 0x00000000 +#define MASK_PsBumpTextureFromB 0x00000010 +#define MASK_PsBumpTextureFromC 0x00000020 +#define MASK_PsDataType 0x0000000F +#define MASK_PsPointList 0x00000000 +#define MASK_PsLineList 0x00000004 +#define MASK_PsLineStrip 0x00000005 +#define MASK_PsTriangleList 0x00000008 +#define MASK_PsTriangleStrip 0x00000009 +#define MASK_PsTriangleFan 0x0000000A +/* + * REG_3D_PrimitiveSet - Fire Primitive Mask (89F8h-89FBh) + */ +#define MASK_DrawPrimitiveCommand 0x00000007 +#define MASK_SetFirePosition 0x00001F00 +#define MASK_BumpTextureFrom 0x00030000 +#define MASK_Texture1From 0x000C0000 +#define MASK_Texture0From 0x00300000 +#define MASK_ShadingMode 0x07000000 +#define MASK_CullDirection 0x08000000 +/* + * Command Queue Length Mask (89FCh-89FF) + */ +#define MASK_CmdQueueLen 0x0FFF0000 + +/* + * REG_3D_TEnable - Capability Enable Mask (8A00h-8A03h) + */ +#define MASK_DitherEnable 0x00000001 +#define MASK_BlendEnable 0x00000002 +#define MASK_FogTestEnable 0x00000004 +#define MASK_FogEnable 0x00000008 +#define MASK_SpecularEnable 0x00000010 +#define MASK_FogPerspectiveEnable 0x00000020 +#define MASK_TextureCacheClear 0x00000040 +#define MASK_TextureCacheEnable 0x00000080 +#define MASK_BumpMapEnable 0x00000100 +#define MASK_TexturePerspectiveEnable 0x00000200 +#define MASK_TextureEnable 0x00000400 +#define MASK_CullEnable 0x00000800 +#define MASK_TextureNumUsed 0x0000F000 +#define MASK_AlphaBufferEnable 0x00010000 +#define MASK_AlphaTestEnable 0x00020000 +#define MASK_AlphaWriteEnable 0x00040000 +#define MASK_ZTestEnable 0x00080000 +#define MASK_ZWriteEnable 0x00100000 +#define MASK_StencilBufferEnable 0x00200000 +#define MASK_StencilTestEnable 0x00400000 +#define MASK_StencilWriteEnable 0x00800000 +#define MASK_Texture0TransparencyEnable 0x01000000 +#define MASK_Texture1TransparencyEnable 0x02000000 +#define MASK_TextureAWrapUCorrection 0x04000000 +#define MASK_TextureAWrapVCorrection 0x08000000 +#define MASK_TextureBWrapUCorrection 0x10000000 +#define MASK_TextureBWrapVCorrection 0x20000000 +#define MASK_TextureCWrapUCorrection 0x40000000 +#define MASK_TextureCWrapVCorrection 0x80000000 + +/* + * REG_3D_TEnable2 - Capability Enable Mask2 (8A04h-8A07h) + */ +#define MASK_Texture0BlockTextureEnable 0x00000001 +#define MASK_Texture1BlockTextureEnable 0x00000002 +#define MASK_Texture0AnisotropicEnable 0x00000010 +#define MASK_Texture1AnisotropicEnable 0x00000020 +#define MASK_TextureMipmapBiasEnable 0x00000040 +#define MASK_LinePatternEnable 0x00000100 +#define MASK_StippleAlphaEnable 0x00000200 +#define MASK_StippleEnable 0x00000400 +#define MASK_AntiAliasEnable 0x00000800 +#define MASK_ZMaskWriteEnable 0x00001000 +#define MASK_StencilMaskWriteEnable 0x00002000 +#define MASK_AlphaMaskWriteEnable 0x00004000 +#define MASK_ColorMaskWriteEnable 0x00008000 +#define MASK_ZCacheClear 0x00010000 +#define MASK_ZCacheEnable 0x00020000 +#define MASK_StencilCacheClear 0x00040000 +#define MASK_StencilCacheEnable 0x00080000 +#define MASK_AlphaCacheClear 0x00100000 +#define MASK_AlphaCacheEnable 0x00200000 +#define MASK_ColorCacheClear 0x00400000 +#define MASK_ColorCacheEnable 0x00800000 + +/* + * REG_3D_ZSet -- Define Z Buffer Setting Mask (8A08h-8A0Bh) + */ +#define MASK_ZBufferPitch 0x00000FFF +#define MASK_ZTestMode 0x00070000 +#define MASK_ZBufferInSystem 0x00080000 +#define MASK_ZBufferFormat 0x01F00000 + +/* + * REG_3D_ZBias -- Define Z Buffer Setting Mask (8A0Ch-8A0Fh) + */ +#define MASK_ZBias 0xFFFFFFFF + +/* + * REG_3D_ZStWriteMask -- Define Z and Stencil Buffer Mask (8A10h-8A13h) + */ +#define MASK_ZWriteMask 0x00FFFFFF + +/* + * REG_3D_ZAddress -- Define Z Buffer Base Address(8A14h-8A17h) + */ +#define MASK_ZAddress 0xFFFFFFFF + +/* + * REG_3D_AlphaSet -- Define Alpha Buffer Setting Mask (8A18h-8A1Bh) + */ +#define MASK_AlphaBufferPitch 0x000003FF +#define MASK_AlphaRefValue 0x00FF0000 +#define MASK_AlphaTestMode 0x07000000 +#define MASK_AlphaBufferInSystem 0x08000000 +#define MASK_AlphaBufferFormat 0x30000000 + +/* + * REG_3D_AlphaAddress -- Define Alpha Buffer Base Address(8A1Ch-8A1Fh) + */ +#define MASK_AlphaAddress 0xFFFFFFFF + +/* + * REG_3D_DstSet -- Define Destination Buffer Setting Mask (8A20h-8A23h) + */ +#define MASK_DstBufferPitch 0x00000FFF +#define MASK_DstBufferFormat 0x000F0000 +#define MASK_DstBufferBitDepth 0x00300000 +#define MASK_DstBufferRgbOrder 0x00400000 +#define MASK_DstBufferInSystem 0x00800000 +#define MASK_Dst7BitFormat 0x007F0000 +#define MASK_ROP2 0x0F000000 + +/* + * REG_3D_DstAlphaWriteMask -- Define Destination/Alpha Buffer Write Mask (8A24h-8A27h) + */ +#define MASK_ColorWriteMask 0x00FFFFFF +#define MASK_AlphaWriteMask 0xFF000000 + +/* + * REG_3D_DstAddress -- Define Destination Buffer Base Address(8A1Ch-8A1Fh) + */ +#define MASK_DstAddress 0xFFFFFFFF + +/* + * REG_3D_LinePattern -- Define Line Pattern (8A2Ch-8A2Fh) + */ +#define MASK_LinePatternRepeatFactor 0x00007FFF +#define MASK_LinePatternLastPixelFlag 0x00008000 +#define MASK_LinePattern 0xFFFF0000 + +/* + * REG_3D_FogSet -- Define Fog Mask (8A30h-8A33h) + */ +#define MASK_FogColor 0x00FFFFFF +#define MASK_FogMode 0x07000000 +#define MASK_FogZLookup 0x08000000 + +/* + * REG_3D_FogStartEnd -- Define Fog Start End Setting (8A34h-8A37h) + */ +#define MASK_FogFarDistance 0x0007FFFF + +/* + * REG_3D_FogStartEnd -- Define Fog End Setting (8A38h-8A3Bh) + */ +#define MASK_FogInvFarDistance 0x0007FFFF + +#define MASK_FogDensity 0x0003FFFF +#define MASK_FogFactor 0xFF000000 + +#define MASK_StencilMaskValue 0x000000FF +#define MASK_StencilReferenceValue 0x0000FF00 +#define MASK_StencilTestMode 0x07000000 +#define MASK_StencilBufferInSystem 0x08000000 +#define MASK_StencilFormat 0x30000000 + +#define MASK_StencilMode_ALWAYS 0x07000000 +#define MASK_StencilBufferPitch 0x00000FFF +#define MASK_StencilZPassOp 0x00007000 +#define MASK_StencilZFailOp 0x00070000 +#define MASK_StencilFailOp 0x00700000 +#define MASK_StencilWriteMask 0xFF000000 + +#define MASK_StencilZPassOp_REPLACE 0x00002000 +#define MASK_StencilZFailOp_REPLACE 0x00020000 +#define MASK_StencilFailOp_REPLACE 0x00200000 +#define MASK_StencilAddress 0xFFFFFFFF + +#define MASK_SrcBlendMode 0x0000000F +#define MASK_DstBlendMode 0x000000F0 +#define MASK_DSTBLEND_ZERO 0x00000000 +#define MASK_DSTBLEND_ONE 0x00000010 +#define MASK_DSTBLEND_SRC_COLOR 0x00000020 +#define MASK_DSTBLEND_INV_SRC_COLOR 0x00000030 +#define MASK_DSTBLEND_SRC_ALPHA 0x00000040 +#define MASK_DSTBLEND_INV_SRC_ALPHA 0x00000050 +#define MASK_DSTBLEND_DST_ALPHA 0x00000060 +#define MASK_DSTBLEND_INV_DST_ALPHA 0x00000070 +#define MASK_DSTBLEND_DST_COLOR 0x00000080 +#define MASK_DSTBLEND_INV_DST_COLOR 0x00000090 +#define MASK_DSTBLEND_SRC_ALPHA_SAT 0x000000A0 + +#define MASK_SRCBLEND_ZERO 0x00000000 +#define MASK_SRCBLEND_ONE 0x00000001 +#define MASK_SRCBLEND_SRC_COLOR 0x00000002 +#define MASK_SRCBLEND_INV_SRC_COLOR 0x00000003 +#define MASK_SRCBLEND_SRC_ALPHA 0x00000004 +#define MASK_SRCBLEND_INV_SRC_ALPHA 0x00000005 +#define MASK_SRCBLEND_DST_ALPHA 0x00000006 +#define MASK_SRCBLEND_INV_DST_ALPHA 0x00000007 +#define MASK_SRCBLEND_DST_COLOR 0x00000008 +#define MASK_SRCBLEND_INV_DST_COLOR 0x00000009 +#define MASK_SRCBLEND_SRC_ALPHA_SAT 0x0000000A +#define MASK_SRCBLEND_BOTH_SRC_ALPHA 0x0000000B +#define MASK_SRCBLEND_BOTH_INV_SRC_ALPHA 0x0000000C + +#define MASK_BottomClip 0x00001FFF +#define MASK_TopClip 0x03FFE000 + +#define MASK_RightClip 0x00001FFF +#define MASK_LeftClip 0x03FFE000 + +#define MASK_BMMemoryInSystem 0x00000080 +#define MASK_BMHeight 0x00000F00 +#define MASK_BMWidth 0x0000F000 +#define MASK_BMFilter 0x00010000 +#define MASK_BMMappingMode 0x007E0000 +#define MASK_BMFormat 0x07800000 +#define MASK_BMTxBumpmap 0x08000000 + +#define MASK_BMAddress 0xFFFFFFFC + +#define MASK_BMOffset 0xFF800000 +#define MASK_BMScale 0x007FE000 +#define MASK_BMPitch 0x00001FFF + +#define MASK_BMMatrix00 0x000007FF +#define MASK_BMMatrix01 0x07FF0000 +#define MASK_BMMatrix10 0x000007FF +#define MASK_BMMatrix11 0x07FF0000 + +#define MASK_TextureHeight 0x0000000F +#define MASK_TextureWidth 0x000000F0 +#define MASK_TextureLevel 0x00000F00 +#define MASK_TextureSignYUVFormat 0x00001000 +#define MASK_TextureMappingMode 0x00FF0000 +#define MASK_TextureWrapU 0x00010000 +#define MASK_TextureWrapV 0x00020000 +#define MASK_TextureMirrorU 0x00040000 +#define MASK_TextureMirrorV 0x00080000 +#define MASK_TextureClampU 0x00100000 +#define MASK_TextureClampV 0x00200000 +#define MASK_TextureBorderU 0x00400000 +#define MASK_TextureBorderV 0x00800000 +#define MASK_TextureFormat 0xFF000000 +#define MASK_TextureBitDepth 0x70000000 +#define MASK_TextureRgbOrder 0x80000000 + +#define MASK_TextureAnisotropyRatio 0x0000000F +#define MASK_TextureMipmapLodBias 0x00003FF0 +#define MASK_TextureFilterMin 0x0001C000 +#define MASK_TextureFilterMag 0x00020000 +#define MASK_TextureFilter 0x0003C000 +#define MASK_TextureLevelInSystem 0x3FFC0000 +#define MASK_TextureLevel0InSystem 0x00040000 +#define MASK_TextureBlockLength 0xF0000000 + +#define MASK_TextureTransparencyColorHighB 0x000000FF +#define MASK_TextureTransparencyColorHighG 0x0000FF00 +#define MASK_TextureTransparencyColorHighR 0x00FF0000 +#define MASK_TextureAlphaTransparencyMode 0x08000000 + +#define MASK_TextureTransparencyColorLowB 0x000000FF +#define MASK_TextureTransparencyColorLowG 0x0000FF00 +#define MASK_TextureTransparencyColorLowR 0x00FF0000 +#define MASK_TextureBlockHeight 0x07000000 +#define MASK_TextureBlockWidth 0x70000000 + +#define MASK_TextureBorderColorB 0x000000FF +#define MASK_TextureBorderColorG 0x0000FF00 +#define MASK_TextureBorderColorR 0x00FF0000 +#define MASK_TextureBorderColorA 0xFF000000 + +#define MASK_TexturePitchOdd 0x000003FF +#define MASK_TexturePitchEven 0x03FF0000 +#define SHIFT_TexturePitchEven 16 + +#define MASK_TextureRealInSystem 0x00000001 +#define MASK_TextureDowngrade 0x00000002 + +#define OP_3D_POINT_DRAW 0x00000000 +#define OP_3D_LINE_DRAW 0x00000001 +#define OP_3D_TRIANGLE_DRAW 0x00000002 + +#define OP_3D_DIRECTION_RIGHT 0x00000000 +#define OP_3D_DIRECTION_LEFT 0x00000100 +#define OP_3D_DIRECTION_HORIZONTAL 0x00000000 +#define OP_3D_DIRECTION_VERTICAL 0x00000100 + +#define OP_3D_FIRE_TFIRE 0x00000000 +#define OP_3D_FIRE_TSARGBa 0x00000100 +#define OP_3D_FIRE_TSWa 0x00000200 +#define OP_3D_FIRE_TSVAa 0x00000300 +#define OP_3D_FIRE_TSVBa 0x00000400 +#define OP_3D_FIRE_TSVCa 0x00000500 + +#define OP_3D_FIRE_TSARGBb 0x00000900 +#define OP_3D_FIRE_TSWb 0x00000a00 +#define OP_3D_FIRE_TSVAb 0x00000b00 +#define OP_3D_FIRE_TSVBb 0x00000c00 +#define OP_3D_FIRE_TSVCb 0x00000d00 + +#define OP_3D_FIRE_TSARGBc 0x00001100 +#define OP_3D_FIRE_TSWc 0x00001200 +#define OP_3D_FIRE_TSVAc 0x00001300 +#define OP_3D_FIRE_TSVBc 0x00001400 +#define OP_3D_FIRE_TSVCc 0x00001500 + +#define OP_3D_Texture0FromA 0x00000000 +#define OP_3D_Texture0FromB 0x00100000 +#define OP_3D_Texture0FromC 0x00200000 +#define OP_3D_Texture1FromA 0x00000000 +#define OP_3D_Texture1FromB 0x00040000 +#define OP_3D_Texture1FromC 0x00080000 +#define OP_3D_TextureBumpFromA 0x00000000 +#define OP_3D_TextureBumpFromB 0x00010000 +#define OP_3D_TextureBumpFromC 0x00020000 + +#define SHADE_FLAT_VertexA 0x01000000 +#define SHADE_FLAT_VertexB 0x02000000 +#define SHADE_FLAT_VertexC 0x03000000 +#define SHADE_GOURAUD 0x04000000 + +#define Z_BUFFER_FORMAT_Z16 0x00000000 +#define Z_BUFFER_FORMAT_Z16_INT 0x00100000 +#define Z_BUFFER_FORMAT_S1Z15 0x00400000 +#define Z_BUFFER_FORMAT_S1Z15_INT 0x00500000 +#define Z_BUFFER_FORMAT_Z32 0x00800000 +#define Z_BUFFER_FORMAT_S1Z31 0x00C00000 +#define Z_BUFFER_FORMAT_S2Z30 0x00D00000 +#define Z_BUFFER_FORMAT_S4Z28 0x00E00000 +#define Z_BUFFER_FORMAT_S8Z24 0x00F00000 +#define Z_BUFFER_FORMAT_FZ30 0x01800000 +#define Z_BUFFER_FORMAT_FS1Z30 0x01C00000 +#define Z_BUFFER_FORMAT_FS2Z30 0x01D00000 +#define MASK_Z_BUFFER_FORMAT 0x01F00000 + +#define ALPHA_BUFFER_FORMAT_1 0x00000000 +#define ALPHA_BUFFER_FORMAT_2 0x10000000 +#define ALPHA_BUFFER_FORMAT_4 0x20000000 +#define ALPHA_BUFFER_FORMAT_8 0x30000000 + +#define DST_FORMAT_RGB_555 0x00100000 +#define DST_FORMAT_RGB_565 0x00110000 +#define DST_FORMAT_ARGB_1555 0x00120000 +#define DST_FORMAT_ARGB_4444 0x00130000 +#define DST_FORMAT_ARGB_1888 0x00300000 +#define DST_FORMAT_ARGB_2888 0x00310000 +#define DST_FORMAT_ARGB_4888 0x00320000 +#define DST_FORMAT_ARGB_8888 0x00330000 +#define DST_FORMAT_ARGB_0888 0x00340000 + +#define DST_FORMAT_BGR_555 0x00500000 +#define DST_FORMAT_BGR_565 0x00510000 +#define DST_FORMAT_ABGR_1555 0x00520000 +#define DST_FORMAT_ABGR_4444 0x00530000 +#define DST_FORMAT_ABGR_1888 0x00700000 +#define DST_FORMAT_ABGR_2888 0x00710000 +#define DST_FORMAT_ABGR_4888 0x00720000 +#define DST_FORMAT_ABGR_8888 0x00730000 +#define DST_FORMAT_ABGR_0888 0x00740000 + +#define MASK_TEXTURE_FORMAT 0xFF000000 + +#define TEXEL_INDEX1 0x00000000 +#define TEXEL_INDEX2 0x01000000 +#define TEXEL_INDEX4 0x02000000 +#define TEXEL_INDEX8 0x03000000 + +#define TEXEL_INDEX1WithAlpha 0x04000000 +#define TEXEL_INDEX2WithAlpha 0x05000000 +#define TEXEL_INDEX4WithAlpha 0x06000000 +#define TEXEL_INDEX8WithAlpha 0x07000000 + +#define TEXEL_I1 0x10000000 +#define TEXEL_I2 0x11000000 +#define TEXEL_I4 0x12000000 +#define TEXEL_I8 0x13000000 + +#define TEXEL_DXT1 0x19000000 +#define TEXEL_DXT2 0x1A000000 +#define TEXEL_DXT3 0x1B000000 + +#define TEXEL_YUV422 0x20000000 +#define TEXEL_YVU422 0x21000000 +#define TEXEL_UVY422 0x22000000 +#define TEXEL_VUY422 0x23000000 +#define TEXEL_YUV411 0x24000000 + +#define TEXEL_L1 0x30000000 +#define TEXEL_L2 0x31000000 +#define TEXEL_L4 0x32000000 +#define TEXEL_L8 0x33000000 + +#define TEXEL_AL11 0x34000000 +#define TEXEL_AL44 0x35000000 +#define TEXEL_AL26 0x37000000 +#define TEXEL_AL88 0x38000000 + +#define TEXEL_A1 0x40000000 +#define TEXEL_A2 0x41000000 +#define TEXEL_A4 0x42000000 +#define TEXEL_A8 0x43000000 + +#define TEXEL_RGB_332_8 0x50000000 +#define TEXEL_RGB_233_8 0x51000000 +#define TEXEL_RGB_232_8 0x52000000 +#define TEXEL_ARGB_1232_8 0x53000000 +#define TEXEL_ARGB_2222_8 0x54000000 + +#define TEXEL_RGB_555_16 0x60000000 +#define TEXEL_RGB_565_16 0x61000000 +#define TEXEL_ARGB_1555_16 0x62000000 +#define TEXEL_ARGB_4444_16 0x63000000 + +#define TEXEL_ARGB_1888_32 0x70000000 +#define TEXEL_ARGB_2888_32 0x71000000 +#define TEXEL_ARGB_4888_32 0x72000000 +#define TEXEL_ARGB_8888_32 0x73000000 +#define TEXEL_ARGB_0888_32 0x74000000 + +#define TEXEL_BGR_332_8 0xD0000000 +#define TEXEL_BGR_233_8 0xD1000000 +#define TEXEL_BGR_232_8 0xD2000000 +#define TEXEL_ABGR_1232_8 0xD3000000 +#define TEXEL_ABGR_2222_8 0xD4000000 + +#define TEXEL_BGR_555_16 0xE0000000 +#define TEXEL_BGR_565_16 0xE1000000 +#define TEXEL_ABGR_1555_16 0xE2000000 +#define TEXEL_ABGR_4444_16 0xE3000000 + +#define TEXEL_ABGR_1888_32 0xF0000000 +#define TEXEL_ABGR_2888_32 0xF1000000 +#define TEXEL_ABGR_4888_32 0xF2000000 +#define TEXEL_ABGR_8888_32 0xF3000000 +#define TEXEL_ABGR_0888_32 0xF4000000 + +#define TEXEL_VU88 0x00000000 +#define TEXEL_LVU655 0x00800000 +#define TEXEL_LVU888 0x01000000 +#define TEXEL_UV88 0x02000000 +#define TEXEL_LUV655 0x02800000 +#define TEXEL_LUV888 0x03000000 + +#define FOGMODE_CHEAP 0x04000000 +#define FOGMODE_LINEAR 0x05000000 +#define FOGMODE_EXP 0x06000000 +#define FOGMODE_EXP2 0x07000000 + +#define Z_16 0x00000000 +#define S_1_Z_15 0x00400000 +#define Z_32 0x00800000 +#define S_1_Z_31 0x00c00000 +#define S_2_Z_30 0x00d00000 +#define S_4_Z_28 0x00e00000 +#define S_8_Z_24 0x00f00000 + +#define S_1 0x00000000 +#define S_2 0x10000000 +#define S_4 0x20000000 +#define S_8 0x30000000 + +#define TEXTURE_FILTER_NEAREST 0x00000000 +#define TEXTURE_FILTER_LINEAR 0x00004000 +#define TEXTURE_FILTER_NEAREST_MIP_NEAREST 0x00008000 +#define TEXTURE_FILTER_NEAREST_MIP_LINEAR 0x00010000 +#define TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x0000c000 +#define TEXTURE_FILTER_LINEAR_MIP_LINEAR 0x00014000 + +#define A_REPLACE_RGB_STAGE0 0xa1485000 +#define A_REPLACE_A_STAGE0 0xc3230000 +#define L_REPLACE__RGB_STAGE0 0xc1485000 +#define L_REPLACE__A_STAGE0 0x63230000 +#define LA_REPLACE__RGB_STAGE0 0xc1485000 +#define LA_REPLACE__A_STAGE0 0xc3230000 +#define I_REPLACE__RGB_STAGE0 0xc1485000 +#define I_REPLACE__A_STAGE0 0xc3230000 +#define RGB_REPLACE__RGB_STAGE0 0xc1485000 +#define RGB_REPLACE__A_STAGE0 0x63230000 +#define RGBA_REPLACE__RGB_STAGE0 0xc1485000 +#define RGBA_REPLACE__A_STAGE0 0xc3230000 + +#define A_MODULATE_RGB_STAGE0 0xa1485000 +#define A_MODULATE_A_STAGE0 0x63c30000 +#define L_MODULATE__RGB_STAGE0 0xa1705000 +#define L_MODULATE__A_STAGE0 0x63230000 +#define LA_MODULATE__RGB_STAGE0 0xa1705000 +#define LA_MODULATE__A_STAGE0 0x63c30000 +#define I_MODULATE__RGB_STAGE0 0xa1705000 +#define I_MODULATE__A_STAGE0 0x63c30000 +#define RGB_MODULATE__RGB_STAGE0 0xa1705000 +#define RGB_MODULATE__A_STAGE0 0x63230000 +#define RGBA_MODULATE__RGB_STAGE0 0xa1705000 +#define RGBA_MODULATE__A_STAGE0 0x63c30000 + +#define RGB_DECAL__RGB_STAGE0 0xc1485000 +#define RGB_DECAL__A_STAGE0 0x63230000 +#define RGBA_DECAL__RGB_STAGE0 0xc534c001 +#define RGBA_DECAL__A_STAGE0 0x63230000 + +#define A_BLEND_RGB_STAGE0 0xa1485000 +#define A_BLEND_A_STAGE0 0x63c30000 +#define L_BLEND__RGB_STAGE0 0x4530c001 +#define L_BLEND__A_STAGE0 0x63230000 +#define LA_BLEND__RGB_STAGE0 0x4530c001 +#define LA_BLEND__A_STAGE0 0x63c30000 +#define I_BLEND__RGB_STAGE0 0x4530c001 +#define I_BLEND__A_STAGE0 0x46c60001 +#define RGB_BLEND__RGB_STAGE0 0x4530c001 +#define RGB_BLEND__A_STAGE0 0x63230000 +#define RGBA_BLEND__RGB_STAGE0 0x4530c001 +#define RGBA_BLEND__A_STAGE0 0x63c30000 + +#define RGB_STAGE1 0xa1485000 +#define A_STAGE1 0xa3230000 + +#define A_REPLACE_RGB_STAGE1 0xa1485000 +#define A_REPLACE_A_STAGE1 0xe3230000 +#define L_REPLACE__RGB_STAGE1 0xe1485000 +#define L_REPLACE__A_STAGE1 0xa3230000 +#define LA_REPLACE__RGB_STAGE1 0xe1485000 +#define LA_REPLACE__A_STAGE1 0xe3230000 +#define I_REPLACE__RGB_STAGE1 0xe1485000 +#define I_REPLACE__A_STAGE1 0xe3230000 +#define RGB_REPLACE__RGB_STAGE1 0xe1485000 +#define RGB_REPLACE__A_STAGE1 0xa3230000 +#define RGBA_REPLACE__RGB_STAGE1 0xe1485000 +#define RGBA_REPLACE__A_STAGE1 0xe3230000 + +#define A_MODULATE_RGB_STAGE1 0xa1485000 +#define A_MODULATE_A_STAGE1 0xa3e30000 +#define L_MODULATE__RGB_STAGE1 0xa1785000 +#define L_MODULATE__A_STAGE1 0xa3230000 +#define LA_MODULATE__RGB_STAGE1 0xa1785000 +#define LA_MODULATE__A_STAGE1 0xa3e30000 +#define I_MODULATE__RGB_STAGE1 0xa1785000 +#define I_MODULATE__A_STAGE1 0xa3e30000 +#define RGB_MODULATE__RGB_STAGE1 0xa1785000 +#define RGB_MODULATE__A_STAGE1 0xa3230000 +#define RGBA_MODULATE__RGB_STAGE1 0xa1785000 +#define RGBA_MODULATE__A_STAGE1 0xa3e30000 + +#define RGB_DECAL__RGB_STAGE1 0xe1485000 +#define RGB_DECAL__A_STAGE1 0xa3230000 +#define RGBA_DECAL__RGB_STAGE1 0xe5394001 +#define RGBA_DECAL__A_STAGE1 0xa3230000 + +#define A_BLEND_RGB_STAGE1 0xa1485000 +#define A_BLEND_A_STAGE1 0xa3e30000 +#define L_BLEND__RGB_STAGE1 0x45394001 +#define L_BLEND__A_STAGE1 0xa3230000 +#define LA_BLEND__RGB_STAGE1 0x45394001 +#define LA_BLEND__A_STAGE1 0xa3e30000 +#define I_BLEND__RGB_STAGE1 0x45394001 +#define I_BLEND__A_STAGE1 0x4aea0001 +#define RGB_BLEND__RGB_STAGE1 0x45394001 +#define RGB_BLEND__A_STAGE1 0xa3230000 +#define RGBA_BLEND__RGB_STAGE1 0x45394001 +#define RGBA_BLEND__A_STAGE1 0xa3e30000 + + +#define INIT_6327_CapsEnable 0x00000080 +#define INIT_6327_CapsEnable2 0x00000000 + +#define INIT_6327_ZSet 0x00030000 +#define INIT_6327_ZMask 0xffffffff +#define INIT_6327_AlphaSet 0x07000000 +#define INIT_6327_DstSet 0x0C000000 +#define INIT_6327_DstMask 0xffffffff +#define INIT_6327_FogSet 0x04000000 +#define INIT_6327_BlendMode 0x00000001 +#define INIT_6327_TextureSet 0x00030000 +#define INIT_6327_TextureMip 0x00000000 +#define INIT_6327_TextureColorBlend0 0xC1485000 +#define INIT_6327_TextureAlphaBlend0 0x333A0000 +#define INIT_6327_Texture1Set 0x00030000 +#define INIT_6327_Texture1Set2 0x00000000 +#define INIT_6327_TextureColorBlend1 0x294B4000 +#define INIT_6327_TextureAlphaBlend1 0x333A0000 +#define INIT_6327_ParsingSet 0x00000060 + +#define SiS_Z_COMP_NEVER 0x00000000 +#define SiS_Z_COMP_S_LT_B 0x00010000 +#define SiS_Z_COMP_S_EQ_B 0x00020000 +#define SiS_Z_COMP_S_LE_B 0x00030000 +#define SiS_Z_COMP_S_GT_B 0x00040000 +#define SiS_Z_COMP_S_NE_B 0x00050000 +#define SiS_Z_COMP_S_GE_B 0x00060000 +#define SiS_Z_COMP_ALWAYS 0x00070000 + +#define SiS_ALPHA_NEVER 0x00000000 +#define SiS_ALPHA_LESS 0x01000000 +#define SiS_ALPHA_EQUAL 0x02000000 +#define SiS_ALPHA_LEQUAL 0x03000000 +#define SiS_ALPHA_GREATER 0x04000000 +#define SiS_ALPHA_NOTEQUAL 0x05000000 +#define SiS_ALPHA_GEQUAL 0x06000000 +#define SiS_ALPHA_ALWAYS 0x07000000 + +#define SiS_STENCIL_NEVER 0x00000000 +#define SiS_STENCIL_LESS 0x01000000 +#define SiS_STENCIL_EQUAL 0x02000000 +#define SiS_STENCIL_LEQUAL 0x03000000 +#define SiS_STENCIL_GREATER 0x04000000 +#define SiS_STENCIL_NOTEQUAL 0x05000000 +#define SiS_STENCIL_GEQUAL 0x06000000 +#define SiS_STENCIL_ALWAYS 0x07000000 + +#define SiS_SFAIL_KEEP 0x00000000 +#define SiS_SFAIL_ZERO 0x00100000 +#define SiS_SFAIL_REPLACE 0x00200000 +#define SiS_SFAIL_INVERT 0x00500000 +#define SiS_SFAIL_INCR 0x00600000 +#define SiS_SFAIL_DECR 0x00700000 + +#define SiS_SPASS_ZFAIL_KEEP 0x00000000 +#define SiS_SPASS_ZFAIL_ZERO 0x00010000 +#define SiS_SPASS_ZFAIL_REPLACE 0x00020000 +#define SiS_SPASS_ZFAIL_INVERT 0x00050000 +#define SiS_SPASS_ZFAIL_INCR 0x00060000 +#define SiS_SPASS_ZFAIL_DECR 0x00070000 + +#define SiS_SPASS_ZPASS_KEEP 0x00000000 +#define SiS_SPASS_ZPASS_ZERO 0x00001000 +#define SiS_SPASS_ZPASS_REPLACE 0x00002000 +#define SiS_SPASS_ZPASS_INVERT 0x00005000 +#define SiS_SPASS_ZPASS_INCR 0x00006000 +#define SiS_SPASS_ZPASS_DECR 0x00007000 + +#define SiS_D_ZERO 0x00000000 +#define SiS_D_ONE 0x00000010 +#define SiS_D_SRC_COLOR 0x00000020 +#define SiS_D_ONE_MINUS_SRC_COLOR 0x00000030 +#define SiS_D_SRC_ALPHA 0x00000040 +#define SiS_D_ONE_MINUS_SRC_ALPHA 0x00000050 +#define SiS_D_DST_ALPHA 0x00000060 +#define SiS_D_ONE_MINUS_DST_ALPHA 0x00000070 + +#define SiS_S_ZERO 0x00000000 +#define SiS_S_ONE 0x00000001 +#define SiS_S_SRC_ALPHA 0x00000004 +#define SiS_S_ONE_MINUS_SRC_ALPHA 0x00000005 +#define SiS_S_DST_ALPHA 0x00000006 +#define SiS_S_ONE_MINUS_DST_ALPHA 0x00000007 +#define SiS_S_DST_COLOR 0x00000008 +#define SiS_S_ONE_MINUS_DST_COLOR 0x00000009 +#define SiS_S_SRC_ALPHA_SATURATE 0x0000000a + +/* Logic Op */ +#define LOP_CLEAR 0x00000000 +#define LOP_NOR 0x01000000 +#define LOP_AND_INVERTED 0x02000000 +#define LOP_COPY_INVERTED 0x03000000 +#define LOP_AND_REVERSE 0x04000000 +#define LOP_INVERT 0x05000000 +#define LOP_XOR 0x06000000 +#define LOP_NAND 0x07000000 +#define LOP_AND 0x08000000 +#define LOP_EQUIV 0x09000000 +#define LOP_NOOP 0x0a000000 +#define LOP_OR_INVERTED 0x0b000000 +#define LOP_COPY 0x0c000000 +#define LOP_OR_REVERSE 0x0d000000 +#define LOP_OR 0x0e000000 +#define LOP_SET 0x0f000000 + +#define SiSWait3DCmdQueue(wLen)\ +do{ \ + while ( CmdQueLen < (int)(wLen)) { \ + CmdQueLen = (MMIO_IN16(pSiS->IOBase, 0x8240) & pSiS->CmdQueLenMask) - pSiS->CmdQueLenFix; \ + } \ + CmdQueLen -= (int)(wLen); \ +} while(0) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c index aeee2737d..566a1740a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c @@ -1,22 +1,23 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.9 2003/08/07 12:52:23 twini Exp $ */ /* - * 2D Acceleration for SiS 310/325 series (315, 550, 650, 740, M650, 651) + * 2D Acceleration for SiS 315 and Xabre series + * (315/550/650/740/M650/651/652/M652/330/660/M660/760/M760) * - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Thomas Winischhofer not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Winischhofer makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THOMAS WINISCHHOFER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR @@ -24,7 +25,7 @@ * * Based on sis300_accel.c * - * Author: Thomas Winischhofer <thomas@winischhofer.net> + * Author: Thomas Winischhofer <thomas@winischhofer.net> * */ @@ -35,21 +36,49 @@ #include "xf86Pci.h" #include "compiler.h" #include "xaa.h" +#include "xaalocal.h" #include "sis.h" #include "sis310_accel.h" +#if 0 +#define ACCELDEBUG +#endif + #ifdef SISDUALHEAD -/* TW: This is the offset to the memory for each head */ #define HEADOFFSET (pSiS->dhmOffset) #endif -#undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides - * illegal trapezoid data (left and right edges cross each other - * sometimes) which causes drawing errors. +#undef TRAP /* Use/Don't use Trapezoid Fills + * DOES NOT WORK. XAA eventually provides illegal + * trapezoid data (left and right edges cross each + * other) which causes drawing errors. Since + * checking the trapezoid for such a case is very + * time-intensive, it is faster to let it be done + * by the generic polygon functions. */ -#define CTSCE /* Use/Don't use CPUToScreenColorExpand. */ +#define CTSCE /* Use/Don't use CPUToScreenColorExpand. Slower than the + * CPU sometimes, so we disable this on SiS650/740 where + * we know that we're running on a P4. + */ + +#undef INCL_RENDER /* Use/Don't use RENDER extension acceleration + * DOES NOT WORK. The hardware does not support + * ARGB textures, but Alpha Blended BitBlits with + * a static alpha value only. This is completely + * useless as XFree does not provide any environment + * for such a function. The code is kept regardless + * as XFree 5 might support translucent windows where + * this function could make sense. + */ + +#ifdef INCL_RENDER +#ifdef RENDER +#include "mipict.h" +#include "dixstruct.h" +#endif +#endif /* Accelerator functions */ static void SiSInitializeAccelerator(ScrnInfoPtr pScrn); @@ -103,6 +132,31 @@ static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int skipleft); static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); #endif +#ifdef INCL_RENDER +#ifdef RENDER +extern Bool SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, + int op, CARD16 red, CARD16 green, + CARD16 blue, CARD16 alpha, + int alphaType, CARD8 *alphaPtr, + int alphaPitch, int width, + int height, int flags); + +extern Bool SiSSetupForCPUToScreenTexture( ScrnInfoPtr pScrn, + int op, int texType, CARD8 *texPtr, + int texPitch, int width, + int height, int flags); + +extern void SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, + int dstx, int dsty, + int srcx, int srcy, + int width, int height); + +extern CARD32 SiSAlphaTextureFormats[2]; +extern CARD32 SiSTextureFormats[2]; +CARD32 SiSAlphaTextureFormats[2] = { PICT_a8, 0 }; +CARD32 SiSTextureFormats[2] = { PICT_a8r8g8b8, 0 }; +#endif +#endif #ifdef SISDUALHEAD static void SiSRestoreAccelState(ScrnInfoPtr pScrn); @@ -114,10 +168,16 @@ SiSInitializeAccelerator(ScrnInfoPtr pScrn) SISPtr pSiS = SISPTR(pScrn); pSiS->DoColorExpand = FALSE; + if(pSiS->ChipFlags & SiSCF_Integrated) { + /* CmdQueLen = ((128 * 1024) / 4) - 64; - decreases system latecy dramatically */ + CmdQueLen = 0; + } else { + CmdQueLen = ((128 * 1024) / 4) - 64; + } } Bool -SiS310AccelInit(ScreenPtr pScreen) +SiS315AccelInit(ScreenPtr pScreen) { XAAInfoRecPtr infoPtr; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -142,7 +202,7 @@ SiS310AccelInit(ScreenPtr pScreen) /* sync */ infoPtr->Sync = SiSSync; - if ((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) && + if((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) && (pScrn->bitsPerPixel != 32)) return FALSE; @@ -150,7 +210,6 @@ SiS310AccelInit(ScreenPtr pScreen) infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY; - /*| NO_TRANSPARENCY; */ /* solid fills */ infoPtr->SetupForSolidFill = SiSSetupForSolidFill; @@ -187,7 +246,7 @@ SiS310AccelInit(ScreenPtr pScreen) #if 0 /* Screen To Screen Color Expand */ - /* TW: The hardware does not seem to support this the way we need it */ + /* TW: The hardware does not support this the way we need it */ infoPtr->SetupForScreenToScreenColorExpandFill = SiSSetupForScreenToScreenColorExpand; infoPtr->SubsequentScreenToScreenColorExpandFill = @@ -201,18 +260,46 @@ SiS310AccelInit(ScreenPtr pScreen) pSiS->ColorExpandBufferCountMask = 0x0F; pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; #ifdef CTSCE - infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; - infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0]; - infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill; - infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill; - infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline; - infoPtr->ScanlineCPUToScreenColorExpandFillFlags = - NO_PLANEMASK | - CPU_TRANSFER_PAD_DWORD | - SCANLINE_PAD_DWORD | - BIT_ORDER_IN_BYTE_MSBFIRST | - LEFT_EDGE_CLIPPING; + /* 650, 740, 660: We don't use this, it's much slower than doing it by the CPU. + * On 650, 740, 660 we know that we are running on a P4; for other chipsets like + * 315, we don't. On 550, this should be faster than the CPU in any case. + * I now disabled this for the Xabre as well; people owning a "high speed 3D" card + * have presumably CPUs fast enough. + */ + if((pSiS->Chipset != PCI_CHIP_SIS650) && + (pSiS->Chipset != PCI_CHIP_SIS660) && + (pSiS->Chipset != PCI_CHIP_SIS330)) { + infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; + infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0]; + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline; + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING; + } +#endif + +#ifdef INCL_RENDER +#ifdef RENDER + /* Render - DOES NOT WORK */ + if((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32)) { + infoPtr->SetupForCPUToScreenAlphaTexture = SiSSetupForCPUToScreenAlphaTexture; + infoPtr->SubsequentCPUToScreenAlphaTexture = SiSSubsequentCPUToScreenTexture; + infoPtr->CPUToScreenAlphaTextureFormats = SiSAlphaTextureFormats; + infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE | + XAA_RENDER_NO_SRC_ALPHA; + + infoPtr->SetupForCPUToScreenTexture = SiSSetupForCPUToScreenTexture; + infoPtr->SubsequentCPUToScreenTexture = SiSSubsequentCPUToScreenTexture; + infoPtr->CPUToScreenTextureFormats = SiSTextureFormats; + infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE; + } #endif +#endif #ifdef SISDUALHEAD if (pSiS->DualHeadMode) { @@ -312,6 +399,7 @@ static const int sisALUConv[] = 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ }; + /* same ROP but with Pattern as Source */ static const int sisPatALUConv[] = { @@ -361,7 +449,7 @@ static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, /* Set some color depth depending value (see sis_vga.c) */ SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) - /* TW: The 310/325 series is smart enough to know the direction */ + /* The chip is smart enough to know the direction */ } static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, @@ -370,18 +458,41 @@ static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, { SISPtr pSiS = SISPTR(pScrn); long srcbase, dstbase; + int mymin, mymax; PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n", src_x, src_y, dst_x, dst_y, width, height)); srcbase = dstbase = 0; - if (src_y >= 2048) { + mymin = min(src_y, dst_y); + mymax = max(src_y, dst_y); + + /* Although the chip knows the direction to use + * if the source and destination areas overlap, + * that logic fails if we fiddle with the bitmap + * addresses. Therefore, we check if the source + * and destination blitting areas overlap and + * adapt the bitmap addresses synchronously + * if the coordinates exceed the valid range. + * The the areas do not overlap, we do our + * normal check. + */ + if((mymax - mymin) < height) { + if((src_y >= 2048) || (dst_y >= 2048)) { + srcbase = pSiS->scrnOffset * mymin; + dstbase = pSiS->scrnOffset * mymin; + src_y -= mymin; + dst_y -= mymin; + } + } else { + if (src_y >= 2048) { srcbase = pSiS->scrnOffset * src_y; src_y = 0; - } - if ((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { - dstbase = pSiS->scrnOffset*dst_y; + } + if ((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { + dstbase = pSiS->scrnOffset * dst_y; dst_y = 0; + } } #ifdef SISDUALHEAD srcbase += HEADOFFSET; @@ -404,6 +515,11 @@ SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color, PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n", color, rop, planemask)); + if(pSiS->disablecolorkeycurrent) { + if((CARD32)color == pSiS->colorKey) { + rop = 5; /* NOOP */ + } + } SiSSetupPATFG(color) SiSSetupDSTRect(pSiS->scrnOffset, -1) SiSSetupDSTColorDepth(pSiS->DstColor); @@ -439,7 +555,7 @@ SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, SiSDoCMD } -/* TW: Trapezoid */ +/* Trapezoid */ /* This would work better if XAA would provide us with valid trapezoids. * In fact, with small trapezoids the left and the right edge often cross * each other which causes drawing errors (filling over whole scanline). @@ -631,14 +747,14 @@ SiSSetupForDashedLine(ScrnInfoPtr pScrn, SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupStyleLow(*pattern) SiSSetupStyleHigh(*(pattern+4)) - SiSSetupStylePeriod(length-1); /* TW: This was missing!!! */ + SiSSetupStylePeriod(length-1); SiSSetupROP(sisPatALUConv[rop]) SiSSetupPATFG(fg) - SiSSetupCMDFlag(LINE | LINE_STYLE) /* TW: This was missing!!! */ + SiSSetupCMDFlag(LINE | LINE_STYLE) if (bg != -1) { SiSSetupPATBG(bg) } else { - SiSSetupCMDFlag(TRANSPARENT) /* TW: This was missing!!! */ + SiSSetupCMDFlag(TRANSPARENT) } SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) } @@ -724,7 +840,7 @@ SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, SiSDoCMD } -/* TW: Trapezoid */ +/* Trapezoid */ #ifdef TRAP static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, @@ -798,10 +914,10 @@ SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, { SISPtr pSiS=SISPTR(pScrn); - /* TW: FIXME: How do I check the "CPU driven blit stage" on the - * 310/325 series? + /* FIXME: How do I check the "CPU driven blit stage" on the + * 315 series? * That's the 300 series method but definitely wrong for - * 310/325 series (bit 28 is already used for idle!) + * 315 series (bit 28 is already used for idle!) */ /* while ((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x1F00) != 0) {} */ @@ -814,11 +930,11 @@ SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, SiSSetupDSTRect(pSiS->scrnOffset, -1); SiSSetupDSTColorDepth(pSiS->DstColor); if (bg == -1) { - SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF + SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF | pSiS->SiS310_AccelDepth); } else { SiSSetupSRCBG(bg); - SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF + SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF | pSiS->SiS310_AccelDepth); }; } @@ -867,7 +983,7 @@ SiSSubsequentScanlineCPUToScreenColorExpandFill( static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) { - SISPtr pSiS=SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); long cbo; cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; @@ -891,4 +1007,204 @@ SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) } #endif +/* ---- RENDER ---- */ + +/* DOES NOT WORK. SEE COMMENT ABOVE. */ + +#ifdef INCL_RENDER +#ifdef RENDER +static void +SiSRemoveLinear(FBLinearPtr linear) +{ + SISPtr pSiS = (SISPtr)(linear->devPrivate.ptr); + + pSiS->AccelLinearScratch = NULL; +} + +static Bool +SiSAllocateLinear(ScrnInfoPtr pScrn, int sizeNeeded) +{ + SISPtr pSiS = SISPTR(pScrn); + + if(pSiS->AccelLinearScratch) { + if(pSiS->AccelLinearScratch->size >= sizeNeeded) + return TRUE; + else { + if(xf86ResizeOffscreenLinear(pSiS->AccelLinearScratch, sizeNeeded)) + return TRUE; + + xf86FreeOffscreenLinear(pSiS->AccelLinearScratch); + pSiS->AccelLinearScratch = NULL; + } + } + + pSiS->AccelLinearScratch = xf86AllocateOffscreenLinear( + pScrn->pScreen, sizeNeeded, 32, + NULL, SiSRemoveLinear, pSiS); + + return(pSiS->AccelLinearScratch != NULL); +} + +#define RENDER_OP 0xCC /* Has no function whatsoever. No value matters. */ + +Bool +SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, + int op, CARD16 red, CARD16 green, + CARD16 blue, CARD16 alpha, + int alphaType, CARD8 *alphaPtr, + int alphaPitch, int width, + int height, int flags) +{ + SISPtr pSiS = SISPTR(pScrn); + int pitch, sizeNeeded, offset, i; + +#ifdef ACCELDEBUG + xf86DrvMsg(0, X_INFO, "AT: RGB %x %x %x, w %d h %d A-pitch %d\n", + red, green, blue, width, height, alphaPitch); + xf86DrvMsg(0, X_INFO, " %02x %02x %02x %02x %02x %02x %02x %02x\n", + alphaPtr[0],alphaPtr[1],alphaPtr[2],alphaPtr[3], + alphaPtr[4],alphaPtr[5],alphaPtr[6],alphaPtr[7]); +#endif + + if(op != PictOpOver) + return FALSE; + + if((width > 2048) || (height > 2048)) + return FALSE; + + pitch = (width + 31) & ~31; + sizeNeeded = pitch * height; + if(pScrn->bitsPerPixel == 16) /* Texture is always 8888, adapt for AllocLinear */ + sizeNeeded <<= 1; + + if(!SiSAllocateLinear(pScrn, sizeNeeded)) + return FALSE; + + offset = pSiS->AccelLinearScratch->offset << 1; + if(pScrn->bitsPerPixel == 32) + offset <<= 1; + + XAA_888_plus_PICT_a8_to_8888( + (blue >> 8) | (green & 0xff00) | ((red & 0xff00) << 8), + alphaPtr, alphaPitch, (CARD32*)(pSiS->FbBase + offset), + pitch, width, height); + + /* "AGP base" - color depth depending value (see sis_vga.c) */ + SiSSetupDSTColorDepth(pSiS->DstColor); + /* SRC pitch */ + SiSSetupSRCPitch((pitch << 2)); + /* DST pitch and height (-1 for disabling merge-clipping) */ + SiSSetupDSTRect(pSiS->scrnOffset, -1) + /* Init CommandReg and set ROP */ + SiSSetupROP(RENDER_OP) + /* Set command */ + SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO) + + /* Set some color depth depending value (see sis_vga.c) */ + SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) + + /* THIS is the problem: The hardware does not + * support ARGB textures, but a static alpha + * value only. Makes the whole thing pretty + * useless. + */ + SiSSetupAlpha(0x99) + + return TRUE; +} + +Bool +SiSSetupForCPUToScreenTexture(ScrnInfoPtr pScrn, + int op, int texType, CARD8 *texPtr, + int texPitch, int width, + int height, int flags) +{ + SISPtr pSiS = SISPTR(pScrn); + int i, pitch, sizeNeeded, offset; + +#ifdef ACCELDEBUG + xf86DrvMsg(0, X_INFO, "T: type %d op %d w %d h %d T-pitch %d\n", + texType, op, width, height, texPitch); +#endif + + if(op != PictOpOver) + return FALSE; + + if((width > 2048) || (height > 2048)) + return FALSE; + + pitch = (width + 31) & ~31; + sizeNeeded = pitch * height; + if(pScrn->bitsPerPixel == 16) /* Texture is always 8888, adapt for AllocLinear */ + sizeNeeded <<= 1; + + if(!SiSAllocateLinear(pScrn, sizeNeeded)) + return FALSE; + + offset = pSiS->AccelLinearScratch->offset << 1; + if(pScrn->bitsPerPixel == 32) + offset <<= 1; + + { + CARD8 *dst = (CARD8*)(pSiS->FbBase + offset); + i = height; + while(i--) { + memcpy(dst, texPtr, width << 2); + texPtr += texPitch; + dst += pitch << 2; + } + } + + /* "AGP base" - color depth depending value (see sis_vga.c) */ + SiSSetupDSTColorDepth(pSiS->DstColor); + /* SRC pitch */ + SiSSetupSRCPitch((pitch << 4)); + /* DST pitch and height (-1 for disabling merge-clipping) */ + SiSSetupDSTRect(pSiS->scrnOffset, -1) + /* Init CommandReg and set ROP */ + SiSSetupROP(RENDER_OP) + /* Set command */ + SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO) + /* Set some color depth depending value (see sis_vga.c) */ + SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) + + return TRUE; +} + +void +SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, + int dst_x, int dst_y, + int src_x, int src_y, + int width, int height) +{ + SISPtr pSiS = SISPTR(pScrn); + long srcbase, dstbase; + + srcbase = pSiS->AccelLinearScratch->offset << 1; + if(pScrn->bitsPerPixel == 32) + srcbase <<= 1; + +#ifdef ACCELDEBUG + xf86DrvMsg(0, X_INFO, "!: o %x sx %d sy %d dx %d dy %d w %d h %d\n", + srcbase, src_x, src_y, dst_x, dst_y, width, height); +#endif + + dstbase = 0; + if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { + dstbase = pSiS->scrnOffset * dst_y; + dst_y = 0; + } +#ifdef SISDUALHEAD + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; +#endif + SiSSetupSRCBase(srcbase); + SiSSetupDSTBase(dstbase); + SiSSetupRect(width, height) + SiSSetupSRCXY(src_x, src_y) + SiSSetupDSTXY(dst_x, dst_y) + SiSDoCMD +} +#endif +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h index 9a6b20a82..d87e83a8b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h @@ -1,20 +1,23 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h,v 1.7 2003/06/28 14:03:13 twini Exp $ */ /* - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * 2D Acceleration for SiS 315 and Xabre series + * Definitions for the SIS engine communication. + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Thomas Winischhofer not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Winischhofer makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THOMAS WINISCHHOFER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR @@ -22,13 +25,10 @@ * * Based on sis300_accel.h * - * Author: Thomas Winischhofer <thomas@winischhofer.net> + * Author: Thomas Winischhofer <thomas@winischhofer.net> * */ -/* Definitions for the SIS engine communication. */ - - /* SiS310 engine commands */ #define BITBLT 0x00000000 /* Blit */ #define COLOREXP 0x00000001 /* Color expand */ @@ -37,11 +37,11 @@ #define LINE 0x00000004 /* Draw line */ #define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */ #define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */ -#define ALPHA_BLEND 0x00000007 /* Alpha blend ? */ +#define ALPHA_BLEND 0x00000007 /* Alpha blending BitBlt */ #define A3D_FUNCTION 0x00000008 /* 3D command ? */ #define CLEAR_Z_BUFFER 0x00000009 /* ? */ #define GRADIENT_FILL 0x0000000A /* Gradient fill */ -#define STRETCH_BITBLT 0x0000000B /* Stretched Blit */ +#define STRETCH_BITBLT 0x0000000B /* Stretched BitBlit */ /* Command bits */ @@ -62,10 +62,13 @@ #define CLIPENABLE 0x00040000 #define CLIPWITHOUTMERGE 0x04040000 -/* Transparency */ +/* Subfunctions for BitBlt: Transparency */ #define OPAQUE 0x00000000 #define TRANSPARENT 0x00100000 +/* Subfunctions for Alpha Blending BitBlt */ +#define A_UNKNOWN 0x00100000 /* (Blits solid?) */ + /* ? */ #define DSTAGP 0x02000000 #define DSTVIDEO 0x02000000 @@ -132,6 +135,8 @@ #define TRANS_SRC_KEY_HIGH SRC_FGCOLOR #define TRANS_SRC_KEY_LOW SRC_BGCOLOR +#define ALPHA_ALPHA PAT_FGCOLOR + /* Trapezoid registers */ #define TRAP_YH SRC_Y /* 0x8208 */ #define TRAP_LR DST_Y /* 0x820C */ @@ -146,7 +151,7 @@ #define Q_READ_PTR 0x85C8 /* Current read pointer (?) */ #define Q_STATUS 0x85CC /* queue status */ -/* Macros to do useful things with the SIS 310 BitBLT engine */ +/* Macros to do useful things with the SIS 315 BitBLT engine */ /* Q_STATUS: bit 31 = 1: All engines idle and all queues empty @@ -162,20 +167,37 @@ bits 7:0: 2D counter 1 Where is the command queue length (current amount of commands the queue - can accept) on the 310 series? (The current implementation is taken - from 300 series and certainly wrong...) + can accept) on the 315 series? (The current implementation works, but only + as long as there is no 3D driver which uses the queue without your knowledge) */ -int CmdQueLen; +#define CmdQueLen pSiS->cmdQueueLen /* TW: FIXME: CmdQueLen is... where....? */ +/* We assume a length of 4 bytes per command; since 512K of + * of RAM are allocated, the number of commands is easily + * calculated (assuming that there is no 3D support yet) + * We calculate it very cautiously (128K only) and let the + * rest to the (never?)-to-come (?) 3D engine. (The 3D engine + * can use a similar technique, using the remaining 384K, + * hence a queue overflow is avoided) + * UPDATE: using the command queue without syncing totally + * (ie assuming a QueueLength of 0) decreases system latency + * dramatically on the integrated chipsets (sound gets interrupted, + * etc.). We now sync every time... this is a little slower, + * but it keeps the rest of the box somewhat alive... + */ #define SiSIdle \ { \ - while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ - while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ - CmdQueLen=MMIO_IN16(pSiS->IOBase, Q_STATUS); \ + if(pSiS->ChipFlags & SiSCF_Integrated) { \ + /* CmdQueLen = ((128 * 1024) / 4) - 64; - decreases system latecy dramatically */ \ + CmdQueLen = 0; \ + } else { \ + CmdQueLen = ((128 * 1024) / 4) - 64; \ + } \ + while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \ + while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \ } - /* TW: (do twice like on 300 series?) */ #define SiSSetupSRCBase(base) \ if (CmdQueLen <= 0) SiSIdle;\ @@ -338,4 +360,15 @@ int CmdQueLen; MMIO_OUT32(pSiS->IOBase, TRAP_ER, eR);\ CmdQueLen --; +/* Alpha blending BitBlt (alpha = 8 bit) */ +#define SiSSetupAlpha(alpha) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, ALPHA_ALPHA, alpha);\ + CmdQueLen--; + +/* Set Pattern register */ +#define SiSSetPattern(num, value) \ + if (CmdQueLen <= 0) SiSIdle; \ + MMIO_OUT32(pSiS->IOBase, (PATTERN_REG + (num * 4)), value); \ + CmdQueLen--; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c index f47475526..7c9fdf9da 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c @@ -1,40 +1,34 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c,v 1.9 2003/08/07 12:52:23 twini Exp $ */ /* * Xv driver for SiS 5597/5598, 6236 and 530/620. * - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria. + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria. * * Based on sis_video.c which is - * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. - * Parts Copyright 2002 by Thomas Winischhofer, Vienna, Austria. - * All Rights Reserved. + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Author: - * Thomas Winischhofer <thomas@winischhofer.net> + * Author: Thomas Winischhofer <thomas@winischhofer.net> */ #include "sis.h" -#ifdef USE6326VIDEO #include "xf86.h" #include "xf86_OSproc.h" @@ -84,6 +78,7 @@ static void SIS6326InitOffscreenImages(ScreenPtr pScrn); static Atom xvBrightness, xvContrast, xvColorKey; static Atom xvAutopaintColorKey, xvSetDefaults; +static Atom xvDisableGfx; #define IMAGE_MIN_WIDTH 32 /* Minimum and maximum image sizes */ #define IMAGE_MIN_HEIGHT 24 @@ -121,7 +116,7 @@ static CARD8 getvideoreg(SISPtr pSiS, CARD8 reg) return(ret); } -static void setvideoreg(SISPtr pSiS, CARD8 reg, CARD8 data) +static __inline void setvideoreg(SISPtr pSiS, CARD8 reg, CARD8 data) { outSISIDXREG(SISCR, reg, data); } @@ -220,7 +215,7 @@ static XF86VideoFormatRec SIS6326Formats[NUM_FORMATS] = {24, TrueColor} }; -#define NUM_ATTRIBUTES 5 +#define NUM_ATTRIBUTES 6 static XF86AttributeRec SIS6326Attributes[NUM_ATTRIBUTES] = { @@ -228,7 +223,8 @@ static XF86AttributeRec SIS6326Attributes[NUM_ATTRIBUTES] = {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"}, {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, - {XvSettable , 0, 0, "XV_SET_DEFAULTS"} + {XvSettable , 0, 0, "XV_SET_DEFAULTS"}, + {XvSettable | XvGettable, 0, 1, "XV_DISABLE_GRAPHICS"} }; #define NUM_IMAGES 6 @@ -375,6 +371,8 @@ typedef struct { CARD32 colorKey; Bool autopaintColorKey; + Bool disablegfx; + CARD32 videoStatus; Time offTime; Time freeTime; @@ -394,11 +392,14 @@ typedef struct { static void SIS6326SetPortDefaults (ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) { + SISPtr pSiS = SISPTR(pScrn); + pPriv->colorKey = 0x000101fe; pPriv->videoStatus = 0; - pPriv->brightness = 0; - pPriv->contrast = 4; + pPriv->brightness = pSiS->XvDefBri; /* 0; - see sis_opt.c */ + pPriv->contrast = pSiS->XvDefCon; /* 4; */ pPriv->autopaintColorKey = TRUE; + pPriv->disablegfx = pSiS->XvDefDisableGfx; } static void @@ -485,7 +486,7 @@ SIS6326ResetVideo(ScrnInfoPtr pScrn) /* Reset contrast control */ setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, 0x04, 0x1F); - /* Set treshold */ + /* Set threshold */ if(pSiS->oldChipset < OC_SIS6326) { CARD8 temp; inSISIDXREG(SISSR, 0x33, temp); /* Synchronous DRAM Timing? */ @@ -584,12 +585,14 @@ SIS6326SetupImageVideo(ScreenPtr pScreen) xvColorKey = MAKE_ATOM("XV_COLORKEY"); xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); + xvDisableGfx = MAKE_ATOM("XV_DISABLE_GRAPHICS"); SIS6326ResetVideo(pScrn); return adapt; } +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) static Bool RegionsEqual(RegionPtr A, RegionPtr B) { @@ -618,6 +621,7 @@ RegionsEqual(RegionPtr A, RegionPtr B) return TRUE; } +#endif static int SIS6326SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, @@ -626,44 +630,50 @@ SIS6326SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, SISPortPrivPtr pPriv = (SISPortPrivPtr)data; if(attribute == xvBrightness) { - if((value < -128) || (value > 127)) - return BadValue; - pPriv->brightness = value; + if((value < -128) || (value > 127)) + return BadValue; + pPriv->brightness = value; } else if(attribute == xvContrast) { - if((value < 0) || (value > 7)) - return BadValue; - pPriv->contrast = value; + if((value < 0) || (value > 7)) + return BadValue; + pPriv->contrast = value; } else if(attribute == xvColorKey) { - pPriv->colorKey = value; - REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + pPriv->colorKey = value; + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); } else if (attribute == xvAutopaintColorKey) { - if ((value < 0) || (value > 1)) - return BadValue; + if((value < 0) || (value > 1)) + return BadValue; pPriv->autopaintColorKey = value; + } else if(attribute == xvDisableGfx) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->disablegfx = value; } else if (attribute == xvSetDefaults) { - SIS6326SetPortDefaults(pScrn, pPriv); + SIS6326SetPortDefaults(pScrn, pPriv); } else return BadMatch; return Success; } -static int +static int SIS6326GetPortAttribute( - ScrnInfoPtr pScrn, + ScrnInfoPtr pScrn, Atom attribute, - INT32 *value, + INT32 *value, pointer data ){ SISPortPrivPtr pPriv = (SISPortPrivPtr)data; if(attribute == xvBrightness) { - *value = pPriv->brightness; + *value = pPriv->brightness; } else if(attribute == xvContrast) { - *value = pPriv->contrast; + *value = pPriv->contrast; } else if(attribute == xvColorKey) { - *value = pPriv->colorKey; - } else if (attribute == xvAutopaintColorKey) - *value = (pPriv->autopaintColorKey) ? 1 : 0; - else return BadMatch; + *value = pPriv->colorKey; + } else if (attribute == xvAutopaintColorKey) { + *value = (pPriv->autopaintColorKey) ? 1 : 0; + } else if (attribute == xvDisableGfx) { + *value = (pPriv->disablegfx) ? 1 : 0; + } else return BadMatch; return Success; } @@ -722,7 +732,7 @@ calc_scale_factor(SISPtr pSiS, SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, if(temp > 63) temp = 63; pOverlay->HUSF = temp; } else { - /* TW: 6326 can't scale below factor .440 - to check with 530/620 */ + /* 6326 can't scale below factor .440 - to check with 530/620 */ if(((dstW * 1000) / srcW) < 440) dstW = ((srcW * 440) / 1000) + 1; temp = srcW / dstW; if(temp > 15) temp = 15; @@ -742,7 +752,7 @@ calc_scale_factor(SISPtr pSiS, SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, pOverlay->VUSF = temp; pOverlay->PitchMult = 1; } else { - /* TW: 6326 can't scale below factor .440 - to check with 530/620 */ + /* 6326 can't scale below factor .440 - to check with 530/620 */ if(((dstH * 1000) / srcH) < 440) dstH = ((srcH * 440) / 1000) + 1; temp = srcH / dstH; if(srcH % dstH) { @@ -755,7 +765,7 @@ calc_scale_factor(SISPtr pSiS, SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, } } -static void /* V 530/6326 */ +static void calc_line_buf_size(SISOverlayPtr pOverlay) { CARD32 I; @@ -775,7 +785,7 @@ calc_line_buf_size(SISOverlayPtr pOverlay) pOverlay->lineBufSize = (CARD8)I; } -static void /* V 530/6326 */ +static void merge_line_buf(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable) { if(enable) { @@ -785,7 +795,7 @@ merge_line_buf(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable) } } -static void /* V 530/6326 */ +static void set_format(SISPtr pSiS, SISOverlayPtr pOverlay) { CARD8 fmt, misc0, misc1, misc4; @@ -840,7 +850,7 @@ set_format(SISPtr pSiS, SISOverlayPtr pOverlay) } } -static void /* V 6326/530 */ +static void set_colorkey(SISPtr pSiS, CARD32 colorkey) { CARD8 r, g, b, s; @@ -864,13 +874,13 @@ set_colorkey(SISPtr pSiS, CARD32 colorkey) setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Red_Max ,(CARD8)r); } -static void +static __inline void set_brightness(SISPtr pSiS, CARD8 brightness) { setvideoreg(pSiS, Index_VI6326_Brightness, brightness); } -static void +static __inline void set_contrast(SISPtr pSiS, CARD8 contrast) { setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, contrast, 0x07); @@ -896,6 +906,12 @@ set_contrast_data(SISPtr pSiS, int value) setvideoreg(pSiS, Index_VI6326_Contrast_Factor, temp); } +static __inline void +set_disablegfx(SISPtr pSiS, Bool mybool) +{ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, mybool ? 0x10 : 0x00, 0x10); +} + static void set_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index) { @@ -1033,11 +1049,14 @@ set_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index set_contrast(pSiS, pPriv->contrast); } + /* enable/disable graphics display around overlay */ + set_disablegfx(pSiS, pPriv->disablegfx); + /* set format */ set_format(pSiS, pOverlay); } -/* TW: Overlay MUST NOT be switched off while beam is over it */ +/* Overlay MUST NOT be switched off while beam is over it */ static void close_overlay(SISPtr pSiS, SISPortPrivPtr pPriv) { @@ -1271,9 +1290,10 @@ SIS6326PutImage( ){ SISPtr pSiS = SISPTR(pScrn); SISPortPrivPtr pPriv = (SISPortPrivPtr)data; - int totalSize=0; int depth = pSiS->CurrentLayout.bitsPerPixel >> 3; + CARD32 *src, *dest; + unsigned long i; if(pPriv->grabbedByV4L) return Success; @@ -1331,6 +1351,10 @@ SIS6326PutImage( totalSize = pPriv->srcPitch * height; } + /* make it a multiple of 16 to simplify to copy loop */ + totalSize += 15; + totalSize &= ~15; + pPriv->totalSize = totalSize; /* allocate memory (we do doublebuffering) */ @@ -1343,22 +1367,45 @@ SIS6326PutImage( pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; /* copy data */ - memcpy(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); + if((pSiS->XvUseMemcpy) || (totalSize < 16)) { + memcpy(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); + } else { + dest = (CARD32 *)(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf]); + src = (CARD32 *)buf; + for(i = 0; i < (totalSize/16); i++) { + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + } + } SIS6326DisplayVideo(pScrn, pPriv); /* update cliplist */ +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) if( pPriv->autopaintColorKey && - (pPriv->grabbedByV4L || !RegionsEqual(&pPriv->clip, clipBoxes))) { + (pPriv->grabbedByV4L || + !RegionsEqual(&pPriv->clip, clipBoxes)) ) { /* We always paint colorkey for V4L */ - if (!pPriv->grabbedByV4L) - REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + if(!pPriv->grabbedByV4L) + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); /* draw these */ - /* xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); - for X4.2 */ XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); } +#else + if( pPriv->autopaintColorKey && + (pPriv->grabbedByV4L || + !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) ) { + /* We always paint colorkey for V4L */ + if(!pPriv->grabbedByV4L) + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + /* draw these */ + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } +#endif pPriv->currentBuf ^= 1; @@ -1469,7 +1516,7 @@ SIS6326VideoTimerCallback (ScrnInfoPtr pScrn, Time now) } } -/* TW: Offscreen surface stuff for v4l */ +/* Offscreen surface stuff for v4l */ static int SIS6326AllocSurface ( @@ -1611,9 +1658,13 @@ SIS6326DisplaySurface ( SIS6326DisplayVideo(pScrn, pPriv); if(pPriv->autopaintColorKey) { +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); +#else + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); +#endif } pPriv->videoStatus = CLIENT_VIDEO_ON; @@ -1656,7 +1707,5 @@ SIS6326InitOffscreenImages(ScreenPtr pScrn) { xf86XVRegisterOffscreenImages(pScrn, SIS6326OffscreenImages, 2); } -#else -int sis_foo; -#endif + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c index f107599f1..529a08718 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c @@ -1,4 +1,39 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c,v 1.12 1999/05/30 02:28:12 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c,v 1.29 2003/06/26 22:35:17 twini Exp $ */ +/* + * 2D acceleration for SiS5597/5598 and 6326 + * + * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Parts Copyright 2002-2003 Thomas Winischhofer, Vienna, Austria. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk> + * Thomas Winischhofer <thomas@winischhofer.net> + */ + +#if 0 +#define CTSCE /* TW: Include enhanced color expansion code */ +#endif /* This produces drawing errors sometimes */ #include "xf86.h" #include "xf86_OSproc.h" @@ -7,479 +42,612 @@ #include "xf86PciInfo.h" #include "xf86Pci.h" -#include "miline.h" - +#include "sis_accel.h" #include "sis_regs.h" #include "sis.h" #include "xaarop.h" static void SiSSync(ScrnInfoPtr pScrn); - static void SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, - int rop, unsigned int planemask); - + int rop, unsigned int planemask); static void SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, - int y, int w, int h); - + int y, int w, int h); static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, - int xdir, int ydir, int rop, - unsigned int planemask, - int transparency_color); - + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color); static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, - int x1, int y1, int x2, - int y2, int w, int h); - -static void SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, - int patternx, int patterny, int fg, int bg, - int rop, unsigned int planemask); - + int x1, int y1, int x2, + int y2, int w, int h); +static void SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); static void SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, - int patternx, int patterny, int x, int y, - int w, int h); - + int patternx, int patterny, int x, int y, + int w, int h); +#if 0 static void SiSSetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn, - int fg, int bg, - int rop, unsigned int planemask); - + int fg, int bg, + int rop, unsigned int planemask); static void SiSSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, - int x, int y, int w, int h, - int srcx, int srcy, int offset ); - + int x, int y, int w, int h, + int srcx, int srcy, int offset ); +#endif static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn, - int left, int top, int right, int bottom); - + int left, int top, int right, int bottom); static void SiSDisableClipping (ScrnInfoPtr pScrn); - -static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, - int color, int rop, unsigned int planemask); - +static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask); static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, - int x1, int y1, int x2, int y2, int flags); - + int x1, int y1, int x2, int y2, int flags); static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, - int x, int y, int len, int dir); - - -static void SiSInitializeAccelerator(ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); -} + int x, int y, int len, int dir); +#ifdef CTSCE +static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft); +static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#endif -Bool SiSAccelInit(ScreenPtr pScreen) +Bool +SiSAccelInit(ScreenPtr pScreen) { - XAAInfoRecPtr infoPtr; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSiS = SISPTR(pScrn); - BoxRec AvailFBArea; - int offset; + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + BoxRec AvailFBArea; + int topFB, i; + int reservedFbSize; + int UsableFbSize; + unsigned char *AvailBufBase; + + pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + infoPtr->Flags = LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS | + PIXMAP_CACHE; + + /* Sync */ + infoPtr->Sync = SiSSync; - pSiS->AccelInfoRec = infoPtr = XAACreateInfoRec(); - if (!infoPtr) return FALSE; + /* Screen To Screen copy */ + infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK; - SiSInitializeAccelerator(pScrn); + /* Solid fill */ + infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid; + infoPtr->SolidFillFlags = NO_PLANEMASK; - infoPtr->Flags = PIXMAP_CACHE | - OFFSCREEN_PIXMAPS | - LINEAR_FRAMEBUFFER; - - infoPtr->Sync = SiSSync; - /* Clipping and lines only works on 5597 and 6326 + /* On 5597/5598 and 6326, clipping and lines only work for 1024, 2048, 4096 logical width */ - if (pSiS->ValidWidth) { - infoPtr->SetClippingRectangle = SiSSetClippingRectangle; - infoPtr->DisableClipping = SiSDisableClipping; - infoPtr->ClippingFlags = - HARDWARE_CLIP_SOLID_LINE | - HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | - HARDWARE_CLIP_MONO_8x8_FILL | - HARDWARE_CLIP_SOLID_FILL ; - - /* Solid Lines */ - infoPtr->SolidLineFlags = NO_PLANEMASK | - BIT_ORDER_IN_BYTE_MSBFIRST; - - infoPtr->SetupForSolidLine = SiSSetupForSolidLine; - infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; - infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine; + if(pSiS->ValidWidth) { + /* Clipping */ + infoPtr->SetClippingRectangle = SiSSetClippingRectangle; + infoPtr->DisableClipping = SiSDisableClipping; + infoPtr->ClippingFlags = + HARDWARE_CLIP_SOLID_LINE | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_MONO_8x8_FILL | + HARDWARE_CLIP_SOLID_FILL ; + + /* Solid Lines */ + infoPtr->SetupForSolidLine = SiSSetupForSolidLine; + infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; + infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine; + infoPtr->SolidLineFlags = NO_PLANEMASK; } - infoPtr->SolidFillFlags = NO_PLANEMASK; - infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid; - infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid; - - infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK; - infoPtr->SetupForScreenToScreenCopy = - SiSSetupForScreenToScreenCopy; - infoPtr->SubsequentScreenToScreenCopy = - SiSSubsequentScreenToScreenCopy; - - if (pScrn->bitsPerPixel != 24) { + if(pScrn->bitsPerPixel != 24) { + /* 8x8 mono pattern */ + infoPtr->SetupForMono8x8PatternFill = SiSSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMono8x8PatternFillRect; infoPtr->Mono8x8PatternFillFlags = - NO_PLANEMASK | - HARDWARE_PATTERN_PROGRAMMED_BITS | - HARDWARE_PATTERN_PROGRAMMED_ORIGIN | - BIT_ORDER_IN_BYTE_MSBFIRST; - infoPtr->SetupForMono8x8PatternFill = - SiSSetupForMono8x8PatternFill; - infoPtr->SubsequentMono8x8PatternFillRect = - SiSSubsequentMono8x8PatternFillRect; + NO_PLANEMASK | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST; } -#if 0 /* Don't work until we implement skipleft */ - if (pScrn->bitsPerPixel != 24) { - infoPtr->ScreenToScreenColorExpandFillFlags = GXCOPY_ONLY | - CPU_TRANSFER_PAD_DWORD | - SCANLINE_PAD_DWORD | - NO_PLANEMASK | - HARDWARE_PATTERN_PROGRAMMED_BITS | - HARDWARE_PATTERN_PROGRAMMED_ORIGIN | - BIT_ORDER_IN_BYTE_MSBFIRST; - - infoPtr->SetupForScreenToScreenColorExpandFill = - SiSSetupForScreenToScreenColorExpandFill; - infoPtr->SubsequentScreenToScreenColorExpandFill = - SiSSubsequentScreenToScreenColorExpandFill; +#ifdef CTSCE + if(pScrn->bitsPerPixel != 24) { + /* TW: per-scanline color expansion (using indirect method) */ + pSiS->ColorExpandBufferNumber = 4; + pSiS->ColorExpandBufferCountMask = 0x03; + pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31) / 32) * 4; + + infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; + infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0]; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + SiSSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + SiSSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + SiSSubsequentColorExpandScanline; + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING; + } else { + pSiS->ColorExpandBufferNumber = 0; } +#else + pSiS->ColorExpandBufferNumber = 0; #endif + topFB = pSiS->maxxfbmem; + + reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize; + + UsableFbSize = topFB - reservedFbSize; + + /* Layout: (Sizes do not reflect correct proportions) + * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~| + * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor + * topFB + */ + + if(pSiS->ColorExpandBufferNumber) { + AvailBufBase = pSiS->FbBase + UsableFbSize; + for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) { + pSiS->ColorExpandBufferAddr[i] = AvailBufBase + + i * pSiS->PerColorExpandBufferSize; + pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize + + i * pSiS->PerColorExpandBufferSize; + } + } AvailFBArea.x1 = 0; AvailFBArea.y1 = 0; AvailFBArea.x2 = pScrn->displayWidth; - if (pSiS->HWCursor || pSiS->TurboQueue) offset = 262144; - else offset = 0; - AvailFBArea.y2 = (pSiS->FbMapSize - offset) / (pScrn->displayWidth * - pScrn->bitsPerPixel / 8); - if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047; + AvailFBArea.y2 = UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8) - 1; + + if (AvailFBArea.y2 < 0) + AvailFBArea.y2 = 32767; + + if(AvailFBArea.y2 < pScrn->currentMode->VDisplay) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Not enough video RAM for accelerator. At least " + "%dKB needed, %dKB available\n", + ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */ + * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8, + pSiS->maxxfbmem/1024); + pSiS->NoAccel = TRUE; + pSiS->NoXvideo = TRUE; + XAADestroyInfoRec(pSiS->AccelInfoPtr); + pSiS->AccelInfoPtr = NULL; + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Frame Buffer From (%d,%d) To (%d,%d)\n", + AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2); xf86InitFBManager(pScreen, &AvailFBArea); return(XAAInit(pScreen, infoPtr)); } +/* sync */ static void SiSSync(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); sisBLTSync; } -static void -SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, - unsigned int planemask) +/* Clipping */ +static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn, + int left, int top, int right, int bottom) { SISPtr pSiS = SISPTR(pScrn); - sisSETFGCOLOR(color); - sisSETROP(XAACopyROP[rop]); - sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8, - pScrn->displayWidth * pScrn->bitsPerPixel / 8); - /* - * If you don't support a write planemask, and have set the - * appropriate flag, then the planemask can be safely ignored. - * The same goes for the raster-op if only GXcopy is supported. - */ - /*SETWRITEPLANEMASK(planemask);*/ + sisBLTSync; + sisSETCLIPTOP(left,top); + sisSETCLIPBOTTOM(right,bottom); + pSiS->ClipEnabled = TRUE; } -static void -SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +static void SiSDisableClipping (ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - int destaddr, op; - - destaddr = y * pScrn->displayWidth + x; - op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT; - if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL; - destaddr *= (pScrn->bitsPerPixel / 8); - - sisSETHEIGHTWIDTH(h-1, w * (pScrn->bitsPerPixel/8)-1); - sisSETDSTADDR(destaddr); - sisSETCMD(op); - SiSSync(pScrn); + pSiS->ClipEnabled = FALSE; } -static void -SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, - int rop, unsigned int planemask, - int transparency_color) +static const int sisALUConv[] = +{ + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0x88, /* dest &= src; DSa, GXand, 0x1 */ + 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */ + 0xCC, /* dest = src; S, GXcopy, 0x3 */ + 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x66, /* dest = ^src; DSx, GXxor, 0x6 */ + 0xEE, /* dest |= src; DSo, GXor, 0x7 */ + 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */ + 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */ + 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */ + 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */ + 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ +}; +/* same ROP but with Pattern as Source */ +static const int sisPatALUConv[] = +{ + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0xA0, /* dest &= src; DPa, GXand, 0x1 */ + 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */ + 0xF0, /* dest = src; P, GXcopy, 0x3 */ + 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */ + 0xFA, /* dest |= src; DPo, GXor, 0x7 */ + 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */ + 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */ + 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */ + 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */ + 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ +}; + + +/* Screen to screen copy */ +static void +SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color) { SISPtr pSiS = SISPTR(pScrn); - sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8, - pScrn->displayWidth * pScrn->bitsPerPixel / 8); + sisBLTSync; + sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset); + sisSETROP(XAACopyROP[rop]); pSiS->Xdirection = xdir; pSiS->Ydirection = ydir; } -static void -SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, - int y2, int w, int h) +static void +SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w, int h) { SISPtr pSiS = SISPTR(pScrn); int srcaddr, destaddr; int op ; op = sisCMDBLT | sisSRCVIDEO; - if (pSiS->Ydirection == -1) { - op |= sisBOTTOM2TOP; - srcaddr = (y1 + h - 1) * pScrn->displayWidth; - destaddr = (y2 + h - 1) * pScrn->displayWidth; + if(pSiS->Ydirection == -1) { + op |= sisBOTTOM2TOP; + srcaddr = (y1 + h - 1) * pSiS->CurrentLayout.displayWidth; + destaddr = (y2 + h - 1) * pSiS->CurrentLayout.displayWidth; } else { - op |= sisTOP2BOTTOM; - srcaddr = y1 * pScrn->displayWidth; - destaddr = y2 * pScrn->displayWidth; + op |= sisTOP2BOTTOM; + srcaddr = y1 * pSiS->CurrentLayout.displayWidth; + destaddr = y2 * pSiS->CurrentLayout.displayWidth; } - if (pSiS->Xdirection == -1) { - op |= sisRIGHT2LEFT; - srcaddr += x1 + w - 1; - destaddr += x2 + w - 1; + if(pSiS->Xdirection == -1) { + op |= sisRIGHT2LEFT; + srcaddr += x1 + w - 1; + destaddr += x2 + w - 1; } else { - op |= sisLEFT2RIGHT; - srcaddr += x1; - destaddr += x2; + op |= sisLEFT2RIGHT; + srcaddr += x1; + destaddr += x2; } - if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL; - srcaddr *= (pScrn->bitsPerPixel/8); - destaddr *= (pScrn->bitsPerPixel/8); - if ( ((pScrn->bitsPerPixel/8)>1) && (pSiS->Xdirection == -1) ) { - srcaddr += (pScrn->bitsPerPixel/8)-1; - destaddr += (pScrn->bitsPerPixel/8)-1; + if (pSiS->ClipEnabled) + op |= sisCLIPINTRN | sisCLIPENABL; + + srcaddr *= (pSiS->CurrentLayout.bitsPerPixel/8); + destaddr *= (pSiS->CurrentLayout.bitsPerPixel/8); + if(((pSiS->CurrentLayout.bitsPerPixel / 8) > 1) && (pSiS->Xdirection == -1)) { + srcaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1; + destaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1; } + sisBLTSync; sisSETSRCADDR(srcaddr); sisSETDSTADDR(destaddr); - sisSETHEIGHTWIDTH(h-1, w * (pScrn->bitsPerPixel/8)-1); + sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1); sisSETCMD(op); - SiSSync(pScrn); } +/* solid fill */ static void -SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, - int fg, int bg, int rop, unsigned int planemask) +SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) { SISPtr pSiS = SISPTR(pScrn); - unsigned int *patternRegPtr ; - int i ; - int dstpitch; - int mix = XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop); - int isTransparent = ( bg == -1 ); - - dstpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ; - sisSETBGCOLOR(bg); - sisSETFGCOLOR(fg); - sisSETROPFG(rop); - if (!isTransparent) { - sisSETROPBG(0xcc); /* copy */ - } else { - sisSETROPBG(0xAA); /* dst */ - } - sisSETPITCH(0, dstpitch); - sisSETSRCADDR(0); - patternRegPtr = (unsigned int *)sisSETPATREG(); - pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ; - pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ; - for ( i = 0 ; i < 16 /* sisPatternHeight */ ; ) { - patternRegPtr[i++] = patternx ; - patternRegPtr[i++] = patterny ; - } + + sisBLTSync; + sisSETBGROPCOL(XAACopyROP[rop], color); + sisSETFGROPCOL(XAACopyROP[rop], color); + sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset); } static void -SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, - int patterny, int x, int y, int w, int h) +SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) { SISPtr pSiS = SISPTR(pScrn); - int dstaddr; - register unsigned char *patternRegPtr ; - register unsigned char *srcPatternRegPtr ; - register unsigned int *patternRegPtrL ; - int i, k ; - unsigned short tmp; - int shift ; - int op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | - sisPATFG | sisSRCBG ; - if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL; - - dstaddr = ( y * pScrn->displayWidth + x ) * pScrn->bitsPerPixel / 8; - patternRegPtr = sisSETPATREG(); - srcPatternRegPtr = (unsigned char *)pSiS->sisPatternReg ; - shift = 8-patternx ; - for ( i = 0, k = patterny ; i < 8 ; i++, k++ ) { - tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ; - tmp >>= shift ; - patternRegPtr[i] = tmp & 0xff ; - } - patternRegPtrL = (unsigned int *)sisSETPATREG(); - for ( i = 2 ; i < 16 /* sisPatternHeight */; ) { - patternRegPtrL[i++] = patternRegPtrL[0]; - patternRegPtrL[i++] = patternRegPtrL[1]; - } + int destaddr, op; - sisSETDSTADDR(dstaddr); - sisSETHEIGHTWIDTH(h-1, w*(pScrn->bitsPerPixel/8)-1); + destaddr = y * pSiS->CurrentLayout.displayWidth + x; + + op = sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT; + + if(pSiS->ClipEnabled) + op |= sisCLIPINTRN | sisCLIPENABL; + + destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8); + + sisBLTSync; + sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1); + sisSETDSTADDR(destaddr); sisSETCMD(op); - SiSSync(pScrn); } -/* - * setup for screen-to-screen color expansion - */ + +/* 8x8 mono */ static void -SiSSetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn, - int fg, int bg, - int rop, unsigned int planemask) +SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, + int fg, int bg, int rop, unsigned int planemask) { SISPtr pSiS = SISPTR(pScrn); - int isTransparent = ( bg == -1 ); + unsigned int *patternRegPtr; + int i; - /*ErrorF("SISSetupScreenToScreenColorExpand()\n");*/ + (void)XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop); - /* - * check transparency - */ - /* becareful with rop */ - - if (isTransparent) { - sisSETBGCOLOR(bg); - sisSETFGCOLOR(fg); - sisSETROPFG(0xf0); /* pat copy */ - sisSETROPBG(0xAA); /* dst */ + sisBLTSync; + if(bg != -1) { + sisSETBGROPCOL(0xcc, bg); /* copy */ } else { - sisSETBGCOLOR(bg); - sisSETFGCOLOR(fg); - sisSETROPFG(0xf0); /* pat copy */ - sisSETROPBG(0xcc); /* copy */ + sisSETBGROPCOL(0xAA, bg); /* noop */ + } + sisSETFGROPCOL(rop, fg); + sisSETPITCH(0, pSiS->scrnOffset); + sisSETSRCADDR(0); + patternRegPtr = (unsigned int *)sisSETPATREG(); + pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ; + pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ; + for ( i = 0 ; i < 16 /* sisPatternHeight */ ; ) { + patternRegPtr[i++] = patternx ; + patternRegPtr[i++] = patterny ; } } -/* - * executing screen-to-screen color expansion - */ static void -SiSSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, - int x, int y, int w, int h, - int srcx, int srcy, int offset ) -/* Offset needs to be taken into account. By now, is not used */ +SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, + int patterny, int x, int y, int w, int h) { - SISPtr pSiS = SISPTR(pScrn); - int destpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ; - int srcaddr = srcy * destpitch * + srcx ; - int destaddr = y * destpitch + x * pScrn->bitsPerPixel / 8; - int srcpitch ; - int ww ; - int widthTodo ; - int op ; - - op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | sisPATFG | sisSRCBG | sisCMDENHCOLEXP ; - if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL; - - -/* ErrorF("SISSubsequentScreenToScreenColorExpand()\n"); */ -#define maxWidth 144 - /* can't expand more than maxWidth in one time. - it's a work around for scanline greater than maxWidth - */ - destpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ; - srcpitch = ((w + 31)& ~31) /8 ; - sisSETPITCH(srcpitch, destpitch); - widthTodo = w ; - do { - ww = widthTodo < maxWidth ? widthTodo : maxWidth ; - sisSETDSTADDR(destaddr); - sisSETSRCADDR(srcaddr); - sisSETHEIGHTWIDTH(h-1, ww*(pScrn->bitsPerPixel / 8)-1); - sisSETCMD(op); - srcaddr += ww ; - destaddr += ww*pScrn->bitsPerPixel / 8 ; - widthTodo -= ww ; - } while ( widthTodo > 0 ) ; - SiSSync(pScrn); -} + SISPtr pSiS = SISPTR(pScrn); + int dstaddr; + register unsigned char *patternRegPtr; + register unsigned char *srcPatternRegPtr; + register unsigned int *patternRegPtrL; + int i, k; + unsigned short tmp; + int shift; + int op = sisCMDCOLEXP | + sisTOP2BOTTOM | + sisLEFT2RIGHT | + sisPATFG | + sisSRCBG; + + if (pSiS->ClipEnabled) + op |= sisCLIPINTRN | sisCLIPENABL; + + dstaddr = ( y * pSiS->CurrentLayout.displayWidth + x ) * + pSiS->CurrentLayout.bitsPerPixel / 8; -static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn, - int left, int top, int right, int bottom) -{ - SISPtr pSiS = SISPTR(pScrn); + sisBLTSync; - sisSETCLIPTOP(left,top); - sisSETCLIPBOTTOM(right,bottom); - pSiS->ClipEnabled = TRUE; - -} + patternRegPtr = sisSETPATREG(); + srcPatternRegPtr = (unsigned char *)pSiS->sisPatternReg ; + shift = 8 - patternx ; + for ( i = 0, k = patterny ; i < 8 ; i++, k++ ) { + tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ; + tmp >>= shift ; + patternRegPtr[i] = tmp & 0xff; + } + patternRegPtrL = (unsigned int *)sisSETPATREG(); + for ( i = 2 ; i < 16 /* sisPatternHeight */; ) { + patternRegPtrL[i++] = patternRegPtrL[0]; + patternRegPtrL[i++] = patternRegPtrL[1]; + } -static void SiSDisableClipping (ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - pSiS->ClipEnabled = FALSE; + sisSETDSTADDR(dstaddr); + sisSETHEIGHTWIDTH(h-1, w*(pSiS->CurrentLayout.bitsPerPixel/8)-1); + sisSETCMD(op); } +/* Line */ static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, - int color, int rop, unsigned int planemask) + int color, int rop, unsigned int planemask) { SISPtr pSiS = SISPTR(pScrn); - sisSETFGCOLOR(color); - sisSETBGCOLOR(0); - sisSETROP(XAACopyROP[rop]); /* dst */ + sisBLTSync; + sisSETBGROPCOL(XAACopyROP[rop], 0); + sisSETFGROPCOL(XAACopyROP[rop], color); } - static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, - int x1, int y1, int x2, int y2, int flags) + int x1, int y1, int x2, int y2, int flags) { SISPtr pSiS = SISPTR(pScrn); - int op ; + int op ; int major, minor, err,K1,K2, tmp; - op = sisCMDLINE | sisSRCFG; - if ((flags & OMIT_LAST)) op |= sisLASTPIX ; - if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL; + + op = sisCMDLINE | sisSRCFG; + + if ((flags & OMIT_LAST)) + op |= sisLASTPIX; + + if (pSiS->ClipEnabled) + op |= sisCLIPINTRN | sisCLIPENABL; + if ((major = x2 - x1) <= 0) { major = -major; - } else op |= sisXINCREASE;; + } else + op |= sisXINCREASE; + if ((minor = y2 - y1) <= 0) { minor = -minor; - } else op |= sisYINCREASE; - if(minor >= major){ - tmp = minor; minor = major; major = tmp; - } - else op |= sisXMAJOR; + } else + op |= sisYINCREASE; + + if (minor >= major) { + tmp = minor; + minor = major; + major = tmp; + } else + op |= sisXMAJOR; - K1 = (minor-major)<<1; + K1 = (minor - major)<<1; K2 = minor<<1; err = (minor<<1) - major; + sisBLTSync; sisSETXStart(x1); sisSETYStart(y1); sisSETLineSteps((short)K1,(short)K2); sisSETLineErrorTerm((short)err); sisSETLineMajorCount((short)major); sisSETCMD(op); -/* SiSSync(pScrn);*/ } - static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir) { SISPtr pSiS = SISPTR(pScrn); int destaddr, op; - destaddr = y * pScrn->displayWidth + x; + destaddr = y * pSiS->CurrentLayout.displayWidth + x; + op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT; - if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL; - destaddr *= (pScrn->bitsPerPixel / 8); - sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8, - pScrn->displayWidth * pScrn->bitsPerPixel / 8); + if (pSiS->ClipEnabled) + op |= sisCLIPINTRN | sisCLIPENABL; - if(dir == DEGREES_0) - sisSETHEIGHTWIDTH(0, len * (pScrn->bitsPerPixel>>3)-1); - else - sisSETHEIGHTWIDTH(len-1, (pScrn->bitsPerPixel>>3)-1 ); + destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8); + + sisBLTSync; + sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset); + + if(dir == DEGREES_0) { + sisSETHEIGHTWIDTH(0, len * (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1); + } else { + sisSETHEIGHTWIDTH(len - 1, (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1); + } sisSETDSTADDR(destaddr); - sisSETCMD(op); - SiSSync(pScrn); + sisSETCMD(op); } +#ifdef CTSCE +/* TW: ----- CPU To Screen Color Expand (scanline-wise) ------ */ +static void +SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask) +{ + SISPtr pSiS=SISPTR(pScrn); + + pSiS->CommandReg = 0; + + pSiS->CommandReg |= (sisCMDECOLEXP | + sisLEFT2RIGHT | + sisTOP2BOTTOM); + + sisBLTSync; + + /* TW: The combination of flags in the following + * is not understandable. However, this is the + * only combination that seems to work. + */ + if(bg == -1) { + sisSETROPBG(0xAA); /* dst = dst (=noop) */ + pSiS->CommandReg |= sisSRCFG; + } else { + sisSETBGROPCOL(sisPatALUConv[rop], bg); + pSiS->CommandReg |= sisSRCFG | sisPATBG; + } + + sisSETFGROPCOL(sisALUConv[rop], fg); + + sisSETDSTPITCH(pSiS->scrnOffset); +} + + +static void +SiSSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, int y, int w, + int h, int skipleft) +{ + SISPtr pSiS = SISPTR(pScrn); + int _x0, _y0, _x1, _y1; + int op = pSiS->CommandReg; + + if(skipleft > 0) { + _x0 = x + skipleft; + _y0 = y; + _x1 = x + w; + _y1 = y + h; + sisSETCLIPTOP(_x0, _y0); + sisSETCLIPBOTTOM(_x1, _y1); + op |= sisCLIPENABL; + } else { + op &= (~(sisCLIPINTRN | sisCLIPENABL)); + } + + sisSETSRCPITCH(((((w+7)/8)+3) >> 2) * 4); + + sisSETHEIGHTWIDTH(1-1, (w * (pSiS->CurrentLayout.bitsPerPixel/8)) - 1); + + pSiS->xcurrent = x; + pSiS->ycurrent = y; + + pSiS->CommandReg = op; +} + +static void +SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + SISPtr pSiS = SISPTR(pScrn); + long cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; + int op = pSiS->CommandReg; + int destaddr; + + destaddr = (pSiS->ycurrent * pSiS->CurrentLayout.displayWidth) + pSiS->xcurrent; + destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8); + + /* TW: Wait until there is no color expansion command in queue */ + /* sisBLTSync; */ + + sisSETSRCADDR(cbo); + + sisSETDSTADDR(destaddr); + + sisSETCMD(op); + + pSiS->ycurrent++; + + /* TW: Wait for eventual color expand commands to finish */ + /* (needs to be done, otherwise the data in the buffer may + * be overwritten while accessed by the hardware) + */ + while((MMIO_IN32(pSiS->IOBase, 0x8284) & 0x80000000)) {} + + sisBLTSync; +} +#endif /* CTSCE */ + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h index e0d2d3f33..5fe9a33e4 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h @@ -1,20 +1,24 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h,v 1.6 2003/06/26 22:35:17 twini Exp $ */ /* + * 2D acceleration for 5597/5598 and 6326 + * Definitions for the SIS engine communication + * * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Parts Copyright 2002,2003 Thomas Winischhofer, Vienna, Austria. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR @@ -28,6 +32,7 @@ * Thomas Winischhofer <thomas@winischhofer.net> */ + /* Definitions for the SIS engine communication. ------------------------------------ */ /* For pre-530 chipsets only!!! */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.c index 667961867..1e16b526d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.c @@ -1,31 +1,35 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.c,v 1.16 2003/08/07 12:52:23 twini Exp $ */ /* + * SiS hardware cursor handling + * * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holders not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. + * Thomas Winischhofer <thomas@winischhofer.net> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.c,v 1.2 2000/02/14 19:20:52 dawes Exp $ */ #include "xf86.h" #include "xf86PciInfo.h" @@ -33,311 +37,1389 @@ #include "vgaHW.h" #include "sis.h" +#include "sis_regs.h" #include "sis_cursor.h" +#if 0 +#define SIS300_USE_ARGB16 +#else +#undef SIS300_USE_ARGB16 +#endif + +extern void SISWaitRetraceCRT1(ScrnInfoPtr pScrn); +extern void SISWaitRetraceCRT2(ScrnInfoPtr pScrn); +extern Bool InRegion(int x, int y, region r); + +/* Helper function for Xabre to convert mono image to ARGB */ +/* The Xabre's cursor engine for CRT2 is buggy and can't + * handle mono cursors. We therefore convert the mono image + * to ARGB + */ +static void +SiSXConvertMono2ARGB(SISPtr pSiS) +{ + unsigned char *src = pSiS->CurMonoSrc; + CARD32 *dest = pSiS->CurARGBDest; + CARD8 chunk, mask; + CARD32 fg = pSiS->CurFGCol | 0xff000000; + CARD32 bg = pSiS->CurBGCol | 0xff000000; + int i,j,k; + + if(!dest || !src) return; + + if(pSiS->UseHWARGBCursor) return; + + for(i = 0; i < 64; i++) { + for(j = 0; j < 8; j++) { + chunk = *(src + 8); mask = *src++; + for(k = 128; k != 0; k >>= 1) { + if(mask & k) *dest++ = 0x00000000; + else if(chunk & k) *dest++ = fg; + else *dest++ = bg; + } + } + src += 8; + } +} + static void SiSShowCursor(ScrnInfoPtr pScrn) { - unsigned char temp; + SISPtr pSiS = SISPTR(pScrn); + unsigned char sridx, cridx; + + /* Backup current indices of SR and CR since we run async:ly + * and might be interrupting an on-going register read/write + */ + sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); - outw(VGA_SEQ_INDEX, 0x8605); /* Unlock Registers */ - outb(VGA_SEQ_INDEX, 0x06); - temp = inb(VGA_SEQ_DATA) | 0x40; - outb(VGA_SEQ_DATA, temp); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + orSISIDXREG(SISSR, 0x06, 0x40); + + outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); } static void SiS300ShowCursor(ScrnInfoPtr pScrn) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + if(pSiS->UseHWARGBCursor) { +#ifdef SIS300_USE_ARGB16 + sis300EnableHWARGB16Cursor() +#else + sis300EnableHWARGBCursor() +#endif + } else { + sis300EnableHWCursor() + } + } else { + /* TW: Head 1 is always CRT2 */ + if(pSiS->UseHWARGBCursor) { +#ifdef SIS300_USE_ARGB16 + sis301EnableHWARGB16Cursor() +#else + sis301EnableHWARGBCursor() +#endif + } else { + sis301EnableHWCursor() + } + } + } else { +#endif + if(pSiS->UseHWARGBCursor) { +#ifdef SIS300_USE_ARGB16 + sis300EnableHWARGB16Cursor() +#else + sis300EnableHWARGBCursor() +#endif + if(pSiS->VBFlags & CRT2_ENABLE) { +#ifdef SIS300_USE_ARGB16 + sis301EnableHWARGB16Cursor() +#else + sis301EnableHWARGBCursor() +#endif + } + } else { + sis300EnableHWCursor() + if(pSiS->VBFlags & CRT2_ENABLE) { + sis301EnableHWCursor() + } + } +#ifdef SISDUALHEAD + } +#endif +} + +static void +SiS310ShowCursor(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); - sis300EnableHWCursor() - if (pSiS->VBFlags) { - sis301EnableHWCursor(); +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + if(pSiS->UseHWARGBCursor) { + sis310EnableHWARGBCursor() + } else { + sis310EnableHWCursor() + } + } else { + /* TW: Head 1 is always CRT2 */ + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301EnableHWCursor330() + } else { + if(pSiS->UseHWARGBCursor) { + sis301EnableHWARGBCursor310() + } else { + sis301EnableHWCursor310() + } + } + } + } else { +#endif + if(pSiS->ChipFlags & SiSCF_XabreCore) { + if(pSiS->UseHWARGBCursor) { + sis310EnableHWARGBCursor() + } else { + sis310EnableHWCursor() + } + if(pSiS->VBFlags & CRT2_ENABLE) { + sis301EnableHWCursor330() + } + } else { + if(pSiS->UseHWARGBCursor) { + sis310EnableHWARGBCursor() + if(pSiS->VBFlags & CRT2_ENABLE) { + sis301EnableHWARGBCursor310() + } + } else { + sis310EnableHWCursor() + if(pSiS->VBFlags & CRT2_ENABLE) { + sis301EnableHWCursor310() + } + } } +#ifdef SISDUALHEAD + } +#endif } static void SiSHideCursor(ScrnInfoPtr pScrn) { - unsigned char temp; + SISPtr pSiS = SISPTR(pScrn); + unsigned char sridx, cridx; + + sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); - outw(VGA_SEQ_INDEX, 0x8605); /* Unlock Registers */ - outb(VGA_SEQ_INDEX, 0x06); - temp = inb(VGA_SEQ_DATA) & 0xBF; - outb(VGA_SEQ_DATA, temp); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + andSISIDXREG(SISSR, 0x06, 0xBF); + + outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); } static void SiS300HideCursor(ScrnInfoPtr pScrn) { - SISPtr pSiS = SISPTR(pScrn); - - sis300DisableHWCursor() - if (pSiS->VBFlags) { + SISPtr pSiS = SISPTR(pScrn); + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode && (!pSiS->ForceCursorOff)) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + sis300DisableHWCursor() + sis300SetCursorPositionY(2000, 0) + } else { + /* TW: Head 1 is always CRT2 */ sis301DisableHWCursor() + sis301SetCursorPositionY(2000, 0) + } + } else { +#endif + sis300DisableHWCursor() + sis300SetCursorPositionY(2000, 0) + if(pSiS->VBFlags & CRT2_ENABLE) { + sis301DisableHWCursor() + sis301SetCursorPositionY(2000, 0) + } +#ifdef SISDUALHEAD + } +#endif +} + +static void +SiS310HideCursor(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode && (!pSiS->ForceCursorOff)) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + sis310DisableHWCursor() + sis310SetCursorPositionY(2000, 0) + } else { + /* TW: Head 1 is always CRT2 */ + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301DisableHWCursor330() + sis301SetCursorPositionY330(2000, 0) + } else { + sis301DisableHWCursor310() + sis301SetCursorPositionY310(2000, 0) + } } + } else { +#endif + sis310DisableHWCursor() + sis310SetCursorPositionY(2000, 0) + if(pSiS->VBFlags & CRT2_ENABLE) { + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301DisableHWCursor330() + sis301SetCursorPositionY330(2000, 0) + } else { + sis301DisableHWCursor310() + sis301SetCursorPositionY310(2000, 0) + } + } +#ifdef SISDUALHEAD + } +#endif } static void SiSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { - unsigned char x_preset = 0; - unsigned char y_preset = 0; - int temp; + SISPtr pSiS = SISPTR(pScrn); + DisplayModePtr mode = pSiS->CurrentLayout.mode; /* pScrn->currentMode; */ + unsigned char x_preset = 0; + unsigned char y_preset = 0; + int temp; + unsigned char sridx, cridx; - outw(VGA_SEQ_INDEX, 0x8605); /* Unlock Registers */ + sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); - if (x < 0) { - x_preset = (-x); - x = 0; - } - if (y < 0) { - y_preset = (-y); - y = 0; - } - outw(VGA_SEQ_INDEX, (x&0xFF)<<8 | 0x1A); - outw(VGA_SEQ_INDEX, (x&0xFF00) | 0x1B); - outw(VGA_SEQ_INDEX, (y&0xFF)<<8 | 0x1D); - outb(VGA_SEQ_INDEX, 0x1E); - temp = inb(VGA_SEQ_DATA) & 0xF8; - outw(VGA_SEQ_INDEX, ((y&0x0700) | (temp<<8)) | 0x1E); - outw(VGA_SEQ_INDEX, x_preset<<8 | 0x1C); - outw(VGA_SEQ_INDEX, y_preset<<8 | 0x1F); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if (x < 0) { + x_preset = (-x); + x = 0; + } + + if (y < 0) { + y_preset = (-y); + y = 0; + } + + if(mode->Flags & V_INTERLACE) y /= 2; + else if(mode->Flags & V_DBLSCAN) y *= 2; + + outSISIDXREG(SISSR, 0x1A, x & 0xff); + outSISIDXREG(SISSR, 0x1B, (x & 0xff00) >> 8); + outSISIDXREG(SISSR, 0x1D, y & 0xff); + + inSISIDXREG(SISSR, 0x1E, temp); + temp &= 0xF8; + outSISIDXREG(SISSR, 0x1E, temp | ((y >> 8) & 0x07)); + + outSISIDXREG(SISSR, 0x1C, x_preset); + outSISIDXREG(SISSR, 0x1F, y_preset); + + outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); +} + +#ifdef SISMERGED +static void +SiSSetCursorPositionMerged(ScrnInfoPtr pScrn1, int x, int y) +{ + SISPtr pSiS = SISPTR(pScrn1); + ScrnInfoPtr pScrn2 = pSiS->CRT2pScrn; + DisplayModePtr mode1 = CDMPTR->CRT1; + DisplayModePtr mode2 = CDMPTR->CRT2; + unsigned short x1_preset = 0, x2_preset = 0; + unsigned short y1_preset = 0, y2_preset = 0; + unsigned short maxpreset; + int x1, y1, x2, y2; + + x += pScrn1->frameX0; + y += pScrn1->frameY0; + + x1 = x - pSiS->CRT1frameX0; + y1 = y - pSiS->CRT1frameY0; + + x2 = x - pScrn2->frameX0; + y2 = y - pScrn2->frameY0; + + maxpreset = 63; + if((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->UseHWARGBCursor)) maxpreset = 31; + + if(x1 < 0) { + x1_preset = (-x1); + if(x1_preset > maxpreset) x1_preset = maxpreset; + x1 = 0; + } + if(y1 < 0) { + y1_preset = (-y1); + if(y1_preset > maxpreset) y1_preset = maxpreset; + y1 = 0; + } + if(x2 < 0) { + x2_preset = (-x2); + if(x2_preset > maxpreset) x2_preset = maxpreset; + x2 = 0; + } + if(y2 < 0) { + y2_preset = (-y2); + if(y2_preset > maxpreset) y2_preset = maxpreset; + y2 = 0; + } + + if(mode1->Flags & V_INTERLACE) { y1 /= 2; y1_preset /= 2; } + else if(mode1->Flags & V_DBLSCAN) { y1 *= 2; y1_preset *= 2; } + + if(mode2->Flags & V_INTERLACE) { y2 /= 2; y2_preset /= 2; } + else if(mode2->Flags & V_DBLSCAN) { y2 *= 2; y2_preset *= 2; } + + if(pSiS->VGAEngine == SIS_300_VGA) { + sis300SetCursorPositionX(x1, x1_preset) + sis300SetCursorPositionY(y1, y1_preset) + sis301SetCursorPositionX(x2 + 13, x2_preset) + sis301SetCursorPositionY(y2, y2_preset) + } else { + sis310SetCursorPositionX(x1, x1_preset) + sis310SetCursorPositionY(y1, y1_preset) + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301SetCursorPositionX330(x2 + 17, x2_preset) + sis301SetCursorPositionY330(y2, y2_preset) + } else { + sis301SetCursorPositionX310(x2 + 17, x2_preset) + sis301SetCursorPositionY310(y2, y2_preset) + } + } } +#endif static void SiS300SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + DisplayModePtr mode = pSiS->CurrentLayout.mode; /* pScrn->currentMode; */ + unsigned short x_preset = 0; + unsigned short y_preset = 0; - unsigned char x_preset = 0; - unsigned char y_preset = 0; +#ifdef SISMERGED + if(pSiS->MergedFB) { + SiSSetCursorPositionMerged(pScrn, x, y); + return; + } +#endif - if (x < 0) { - x_preset = (-x); - x = 0; - } - if (y < 0) { - y_preset = (-y); - y = 0; + if (x < 0) { + x_preset = (-x); + x = 0; + } + if (y < 0) { + y_preset = (-y); + y = 0; + } + + if(mode->Flags & V_INTERLACE) y /= 2; + else if(mode->Flags & V_DBLSCAN) y *= 2; + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + sis300SetCursorPositionX(x, x_preset) + sis300SetCursorPositionY(y, y_preset) + } else { + /* TW: Head 1 is always CRT2 */ + sis301SetCursorPositionX(x + 13, x_preset) + sis301SetCursorPositionY(y, y_preset) } - sis300SetCursorPositionX(x, x_preset) - sis300SetCursorPositionY(y, y_preset) - if (pSiS->VBFlags) { - sis301SetCursorPositionX(x, x_preset) - sis301SetCursorPositionY(y, y_preset) + } else { +#endif + sis300SetCursorPositionX(x, x_preset) + sis300SetCursorPositionY(y, y_preset) + if(pSiS->VBFlags & CRT2_ENABLE) { + sis301SetCursorPositionX(x + 13, x_preset) + sis301SetCursorPositionY(y, y_preset) + } +#ifdef SISDUALHEAD + } +#endif +} + +static void +SiS310SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + SISPtr pSiS = SISPTR(pScrn); + DisplayModePtr mode = pSiS->CurrentLayout.mode; + unsigned short x_preset = 0; + unsigned short y_preset = 0; + +#ifdef SISMERGED + if(pSiS->MergedFB) { + SiSSetCursorPositionMerged(pScrn, x, y); + return; + } +#endif + + if (x < 0) { + x_preset = (-x); + x = 0; + } + if (y < 0) { + y_preset = (-y); + y = 0; + } + + if(mode->Flags & V_INTERLACE) y /= 2; + else if(mode->Flags & V_DBLSCAN) y *= 2; + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + sis310SetCursorPositionX(x, x_preset) + sis310SetCursorPositionY(y, y_preset) + } else { + /* TW: Head 1 is always CRT2 */ + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301SetCursorPositionX330(x + 17, x_preset) + sis301SetCursorPositionY330(y, y_preset) + } else { + sis301SetCursorPositionX310(x + 17, x_preset) + sis301SetCursorPositionY310(y, y_preset) + } } + } else { +#endif + sis310SetCursorPositionX(x, x_preset) + sis310SetCursorPositionY(y, y_preset) + if(pSiS->VBFlags & CRT2_ENABLE) { + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301SetCursorPositionX330(x + 17, x_preset) + sis301SetCursorPositionY330(y, y_preset) + } else { + sis301SetCursorPositionX310(x + 17, x_preset) + sis301SetCursorPositionY310(y, y_preset) + } + } +#ifdef SISDUALHEAD + } +#endif } + static void SiSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { - unsigned char f_red, f_green, f_blue; - unsigned char b_red, b_green, b_blue; - - outw(VGA_SEQ_INDEX, 0x8605); - - f_red = (fg & 0x00FF0000) >> (16+2); - f_green = (fg & 0x0000FF00) >> (8+2); - f_blue = (fg & 0x000000FF) >> 2; - b_red = (bg & 0x00FF0000) >> (16+2); - b_green = (bg & 0x0000FF00) >> (8+2); - b_blue = (bg & 0x000000FF) >> 2; - - outw(VGA_SEQ_INDEX, b_red <<8 | 0x14); - outw(VGA_SEQ_INDEX, b_green <<8 | 0x15); - outw(VGA_SEQ_INDEX, b_blue <<8 | 0x16); - outw(VGA_SEQ_INDEX, f_red <<8 | 0x17); - outw(VGA_SEQ_INDEX, f_green <<8 | 0x18); - outw(VGA_SEQ_INDEX, f_blue <<8 | 0x19); + SISPtr pSiS = SISPTR(pScrn); + unsigned char f_red, f_green, f_blue; + unsigned char b_red, b_green, b_blue; + unsigned char sridx, cridx; + + sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + f_red = (fg & 0x00FF0000) >> (16+2); + f_green = (fg & 0x0000FF00) >> (8+2); + f_blue = (fg & 0x000000FF) >> 2; + b_red = (bg & 0x00FF0000) >> (16+2); + b_green = (bg & 0x0000FF00) >> (8+2); + b_blue = (bg & 0x000000FF) >> 2; + + outSISIDXREG(SISSR, 0x14, b_red); + outSISIDXREG(SISSR, 0x15, b_green); + outSISIDXREG(SISSR, 0x16, b_blue); + outSISIDXREG(SISSR, 0x17, f_red); + outSISIDXREG(SISSR, 0x18, f_green); + outSISIDXREG(SISSR, 0x19, f_blue); + + outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); } static void SiS300SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + + if(pSiS->UseHWARGBCursor) return; + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + sis300SetCursorBGColor(bg) + sis300SetCursorFGColor(fg) + } else { + /* TW: Head 1 is always CRT2 */ + sis301SetCursorBGColor(bg) + sis301SetCursorFGColor(fg) + } + } else { +#endif + sis300SetCursorBGColor(bg) + sis300SetCursorFGColor(fg) + if(pSiS->VBFlags & CRT2_ENABLE) { + sis301SetCursorBGColor(bg) + sis301SetCursorFGColor(fg) + } +#ifdef SISDUALHEAD + } +#endif +} + +static void +SiS310SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + SISPtr pSiS = SISPTR(pScrn); - sis300SetCursorBGColor(bg) - sis300SetCursorFGColor(fg) - if (pSiS->VBFlags) { - sis301SetCursorBGColor(bg) - sis301SetCursorFGColor(fg) + if(pSiS->UseHWARGBCursor) return; + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + /* TW: Head 2 is always CRT1 */ + sis310SetCursorBGColor(bg) + sis310SetCursorFGColor(fg) + } else { + /* TW: Head 1 is always CRT2 */ + if(pSiS->ChipFlags & SiSCF_XabreCore) { + if((fg != pSiS->CurFGCol) || (bg != pSiS->CurBGCol)) { + pSiS->CurFGCol = fg; + pSiS->CurBGCol = bg; + SiSXConvertMono2ARGB(pSiS); + } + } else { + sis301SetCursorBGColor310(bg) + sis301SetCursorFGColor310(fg) + } } + } else { +#endif + sis310SetCursorBGColor(bg) + sis310SetCursorFGColor(fg) + + if(pSiS->VBFlags & CRT2_ENABLE) { + if(pSiS->ChipFlags & SiSCF_XabreCore) { + if((fg != pSiS->CurFGCol) || (bg != pSiS->CurBGCol)) { + pSiS->CurFGCol = fg; + pSiS->CurBGCol = bg; + SiSXConvertMono2ARGB(pSiS); + } + } else { + sis301SetCursorBGColor310(bg) + sis301SetCursorFGColor310(fg) + } + } +#ifdef SISDUALHEAD + } +#endif } static void SiSLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { - SISPtr pSiS = SISPTR(pScrn); - int cursor_addr; - unsigned char temp; + SISPtr pSiS = SISPTR(pScrn); + DisplayModePtr mode = pSiS->CurrentLayout.mode; + int cursor_addr; + unsigned char temp; + unsigned char sridx, cridx; - outw(VGA_SEQ_INDEX, 0x8605); + sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); - cursor_addr = pScrn->videoRam - 1; - memcpy((unsigned char *)pSiS->FbBase + cursor_addr * 1024, src, 1024); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif - /* copy bits [21:18] into the top bits of SR38 */ - outb(VGA_SEQ_INDEX, 0x38); - temp = inb(VGA_SEQ_DATA) & 0x0F; - outb(VGA_SEQ_DATA, temp | ((cursor_addr & 0xF00) >> 4)); + cursor_addr = pScrn->videoRam - 1; + if(mode->Flags & V_DBLSCAN) { + int i; + for(i = 0; i < 32; i++) { + memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i), + src + (16 * i), 16); + memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i) + 16, + src + (16 * i), 16); + } + } else { + memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024), src, 1024); + } - /* if set, store the bit [22] to SR3E */ - if (cursor_addr & 0x1000) { - outb(VGA_SEQ_INDEX, 0x3E); - temp = inb(VGA_SEQ_DATA) | 0x04; - outb(VGA_SEQ_DATA, temp); - } + /* copy bits [21:18] into the top bits of SR38 */ + inSISIDXREG(SISSR, 0x38, temp); + temp &= 0x0F; + outSISIDXREG(SISSR, 0x38, temp | ((cursor_addr & 0xF00) >> 4)); - /* set HW cursor pattern, use pattern 0xF */ - outb(VGA_SEQ_INDEX, 0x1E); - temp = inb(VGA_SEQ_DATA) | 0xF0; - outb(VGA_SEQ_DATA, temp); + if(pSiS->Chipset == PCI_CHIP_SIS530) { + /* store the bit [22] to SR3E */ + if(cursor_addr & 0x1000) { + orSISIDXREG(SISSR, 0x3E, 0x04); + } else { + andSISIDXREG(SISSR, 0x3E, ~0x04); + } + } - /* disable the hardware cursor side pattern */ - outb(VGA_SEQ_INDEX, 0x1E); - temp = inb(VGA_SEQ_DATA) & 0xF7; - outb(VGA_SEQ_DATA, temp); + /* set HW cursor pattern, use pattern 0xF */ + orSISIDXREG(SISSR, 0x1E, 0xF0); + + /* disable the hardware cursor side pattern */ + andSISIDXREG(SISSR, 0x1E, 0xF7); + + outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); } static void SiS300LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { - SISPtr pSiS = SISPTR(pScrn); - int cursor_addr; - - if (pSiS->TurboQueue) - cursor_addr = pScrn->videoRam-512-1; /* 1K boundary */ - else - cursor_addr = pScrn->videoRam - 1; /* 1K boundary */ - - memcpy((unsigned char *)pSiS->FbBase + cursor_addr * 1024, src, 1024); - sis300SetCursorAddress(cursor_addr) - sis300SetCursorPatternSelect(0) - if (pSiS->VBFlags) { - sis301SetCursorAddress(cursor_addr) - sis301SetCursorPatternSelect(0) + SISPtr pSiS = SISPTR(pScrn); + int cursor_addr; + CARD32 status1 = 0, status2 = 0; + unsigned char *dest = pSiS->FbBase; + BOOLEAN sizedouble = FALSE; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef SISMERGED + if(pSiS->MergedFB) { + if((CDMPTR->CRT1->Flags & V_DBLSCAN) && (CDMPTR->CRT2->Flags & V_DBLSCAN)) { + sizedouble = TRUE; + } + } else +#endif + if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { + sizedouble = TRUE; + } + + cursor_addr = pScrn->videoRam - pSiS->cursorOffset - (pSiS->CursorSize/1024); /* 1K boundary */ + +#ifdef SISDUALHEAD + /* TW: Use the global (real) FbBase in DHM */ + if(pSiS->DualHeadMode) dest = pSiSEnt->FbBase; +#endif + + if(sizedouble) { + int i; + for(i = 0; i < 32; i++) { + memcpy((unsigned char *)dest + (cursor_addr * 1024) + (32 * i), + src + (16 * i), 16); + memcpy((unsigned char *)dest + (cursor_addr * 1024) + (32 * i) + 16, + src + (16 * i), 16); + } + } else { + memcpy((unsigned char *)dest + (cursor_addr * 1024), src, 1024); + } + + if(pSiS->UseHWARGBCursor) { + if(pSiS->VBFlags & DISPTYPE_CRT1) { + status1 = sis300GetCursorStatus; + sis300DisableHWCursor() + if(pSiS->VBFlags & CRT2_ENABLE) { + status2 = sis301GetCursorStatus; + sis301DisableHWCursor() + } + SISWaitRetraceCRT1(pScrn); + sis300SwitchToMONOCursor(); + if(pSiS->VBFlags & CRT2_ENABLE) { + SISWaitRetraceCRT2(pScrn); + sis301SwitchToMONOCursor(); + } + } + } + sis300SetCursorAddress(cursor_addr); + sis300SetCursorPatternSelect(0); + if(status1) sis300SetCursorStatus(status1) + + if(pSiS->VBFlags & CRT2_ENABLE) { + if((pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) { + status2 = sis301GetCursorStatus; + sis301DisableHWCursor() + SISWaitRetraceCRT2(pScrn); + sis301SwitchToMONOCursor(); + } + sis301SetCursorAddress(cursor_addr) + sis301SetCursorPatternSelect(0) + if(status2) sis301SetCursorStatus(status2) + } + + pSiS->UseHWARGBCursor = FALSE; +} + +static void +SiS310LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned long cursor_addr, cursor_addr2 = 0; + CARD32 status1 = 0, status2 = 0; + unsigned char *dest = pSiS->FbBase; + BOOLEAN sizedouble = FALSE; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef SISMERGED + if(pSiS->MergedFB) { + if((CDMPTR->CRT1->Flags & V_DBLSCAN) && (CDMPTR->CRT2->Flags & V_DBLSCAN)) { + sizedouble = TRUE; + } + } else +#endif + if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { + sizedouble = TRUE; + } + + cursor_addr = pScrn->videoRam - pSiS->cursorOffset - (pSiS->CursorSize/1024); /* 1K boundary */ + +#ifdef SISDUALHEAD + /* TW: Use the global (real) FbBase in DHM */ + if(pSiS->DualHeadMode) dest = pSiSEnt->FbBase; +#endif + + if(sizedouble) { + int i; + for(i = 0; i < 32; i++) { + memcpy((unsigned char *)dest + (cursor_addr * 1024) + (32 * i), + src + (16 * i), 16); + memcpy((unsigned char *)dest + (cursor_addr * 1024) + (32 * i) + 16, + src + (16 * i), 16); + } + } else { + memcpy((unsigned char *)dest + (cursor_addr * 1024), src, 1024); + } + + if(pSiS->ChipFlags & SiSCF_XabreCore) { + + /* Convert Mono image to color image */ + + cursor_addr2 = pScrn->videoRam - pSiS->cursorOffset - ((pSiS->CursorSize/1024) * 2); + + pSiS->CurMonoSrc = (unsigned char *)dest + (cursor_addr * 1024); + pSiS->CurARGBDest = (CARD32 *)((unsigned char *)dest + (cursor_addr2 * 1024)); + + SiSXConvertMono2ARGB(pSiS); + + if(pSiS->UseHWARGBCursor) { + if(pSiS->VBFlags & DISPTYPE_CRT1) { + status1 = sis310GetCursorStatus; + sis310DisableHWCursor(); + SISWaitRetraceCRT1(pScrn); + sis310SwitchToMONOCursor(); + } + } + + } else { + + if(pSiS->UseHWARGBCursor) { + if(pSiS->VBFlags & DISPTYPE_CRT1) { + status1 = sis310GetCursorStatus; + sis310DisableHWCursor() + if(pSiS->VBFlags & CRT2_ENABLE) { + status2 = sis301GetCursorStatus310; + sis301DisableHWCursor310() + } + SISWaitRetraceCRT1(pScrn); + sis310SwitchToMONOCursor(); + if(pSiS->VBFlags & CRT2_ENABLE) { + SISWaitRetraceCRT2(pScrn); + sis301SwitchToMONOCursor310(); + } + } } + } + + sis310SetCursorAddress(cursor_addr); + sis310SetCursorPatternSelect(0); + if(status1) sis310SetCursorStatus(status1) + + if(pSiS->VBFlags & CRT2_ENABLE) { + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301SetCursorAddress330(cursor_addr2) + sis301SetCursorPatternSelect330(0) + } else { + if((pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) { + status2 = sis301GetCursorStatus310; + sis301DisableHWCursor310() + SISWaitRetraceCRT2(pScrn); + sis301SwitchToMONOCursor310(); + } + sis301SetCursorAddress310(cursor_addr) + sis301SetCursorPatternSelect310(0) + if(status2) sis301SetCursorStatus310(status2) + } + } + + pSiS->UseHWARGBCursor = FALSE; } static Bool SiSUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { - return TRUE; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + DisplayModePtr mode = pSiS->CurrentLayout.mode; /* pScrn->currentMode; */ + + if(pSiS->Chipset != PCI_CHIP_SIS6326) return TRUE; + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return TRUE; + if((strcmp(mode->name, "PAL800x600U") == 0) || + (strcmp(mode->name, "NTSC640x480U") == 0)) + return FALSE; + else + return TRUE; } static Bool SiS300UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSiS = SISPTR(pScrn); - - if ( (pSiS->Chipset==PCI_CHIP_SIS540) || - !(pScrn->currentMode->Flags & V_INTERLACE) ) - return TRUE; - else - return FALSE; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + DisplayModePtr mode = pSiS->CurrentLayout.mode; /* pScrn->currentMode; */ +#ifdef SISMERGED + DisplayModePtr mode2 = NULL; + + if(pSiS->MergedFB) { + mode = CDMPTR->CRT1; + mode2 = CDMPTR->CRT2; + } +#endif + + switch (pSiS->Chipset) { + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS540: + if(mode->Flags & V_INTERLACE) + return FALSE; + if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32)) + return FALSE; +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(mode2->Flags & V_INTERLACE) + return FALSE; + if((mode2->Flags & V_DBLSCAN) && (pCurs->bits->height > 32)) + return FALSE; + } +#endif + break; + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: + if(mode->Flags & V_INTERLACE) + return FALSE; + if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32)) + return FALSE; +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(mode2->Flags & V_INTERLACE) + return FALSE; + if((mode2->Flags & V_DBLSCAN) && (pCurs->bits->height > 32)) + return FALSE; + } +#endif + if(pSiS->Chipset == PCI_CHIP_SIS330) { + if((pSiS->VBFlags & CRT2_TV) && + (pSiS->VBFlags & (TV_NTSC|TV_PALM))) { +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(mode2->HDisplay == 1024) return FALSE; + } else +#endif + if(mode->HDisplay == 1024) return FALSE; + } + } + break; + default: + if(mode->Flags & V_INTERLACE) + return FALSE; + if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32)) + return FALSE; + break; + } + return TRUE; } -#ifdef IMP_REALIZE_CURSOR -static unsigned char * -SiSRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) +#ifdef ARGB_CURSOR +#ifdef SIS_ARGB_CURSOR +static Bool +SiSUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs) { - unsigned char *mem; - int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; - int w, h; - int i, j; - unsigned char *srcM, *srcS, *dst, s, m; - - if (!(mem=xcalloc(1,size))) - return NULL; - dst = mem; - - srcS = pCurs->bits->source; - srcM = pCurs->bits->mask; - h = pCurs->bits->height; - if (h > infoPtr->MaxHeight) - h = infoPtr->MaxHeight; - w = (pCurs->bits->width + 31)/32*4; - for (i=0; i<infoPtr->MaxHeight; i++, dst+=16) { - for (j=0; j<infoPtr->MaxWidth/8; j++) { - if (i<h && j<w) { - s = *srcS++; - m = *srcM++; - s = s&m; - m = ~m; - dst[j*2] = ((m&0x01) << 7) | ((s&0x01) << 6) | - ((m&0x02) << 4) | ((s&0x02) << 3) | - ((m&0x04) << 1) | (s&0x04) | - ((m&0x08) >> 2) | ((s&0x08) >> 3) ; - dst[j*2+1] = ((m&0x10) << 3) | ((s&0x10)<<2) | - (m&0x20) | ((s&0x20) >> 1) | - ((m&0x40) >> 3) | ((s&0x40) >> 4) | - ((m&0x80) >> 6) | ((s&0x80) >> 7) ; - } - else { - dst[j*2] = 0xAA; - dst[j*2+1] = 0xAA; - } - } + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + DisplayModePtr mode = pSiS->CurrentLayout.mode; /* pScrn->currentMode; */ +#ifdef SISMERGED + DisplayModePtr mode2 = NULL; + + if(pSiS->MergedFB) { + mode = CDMPTR->CRT1; + mode2 = CDMPTR->CRT2; + } +#endif + + switch (pSiS->Chipset) { + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS540: + if(mode->Flags & V_INTERLACE) + return FALSE; + if(pCurs->bits->height > 32 || pCurs->bits->width > 32) + return FALSE; + if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 16)) + return FALSE; +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(mode2->Flags & V_INTERLACE) + return FALSE; + if((mode2->Flags & V_DBLSCAN) && (pCurs->bits->height > 16)) + return FALSE; + } +#endif + break; + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: + if(mode->Flags & V_INTERLACE) + return FALSE; + if(pCurs->bits->height > 64 || pCurs->bits->width > 64) + return FALSE; + if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32)) + return FALSE; + if((pSiS->CurrentLayout.bitsPerPixel == 8) && (pSiS->VBFlags & CRT2_ENABLE)) + return FALSE; +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(mode2->Flags & V_INTERLACE) + return FALSE; + if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32)) + return FALSE; + } +#endif + if(pSiS->Chipset == PCI_CHIP_SIS330) { + if((pSiS->VBFlags & VB_SISBRIDGE) && + (pSiS->VBFlags & CRT2_TV) && + (pSiS->VBFlags & (TV_NTSC|TV_PALM))) { +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(mode2->HDisplay == 1024) return FALSE; + } else +#endif + if(mode->HDisplay == 1024) return FALSE; + } + } + break; + default: + return FALSE; + } + return TRUE; +} + +static void SiS300LoadCursorImageARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) +{ + SISPtr pSiS = SISPTR(pScrn); + int cursor_addr, i, j, maxheight = 32; + CARD32 *src = pCurs->bits->argb, *p; +#ifdef SIS300_USE_ARGB16 + CARD16 *dest, *pb; + CARD16 temp1; +#define MYSISPTRTYPE CARD16 +#else + CARD32 *pb, *dest; +#define MYSISPTRTYPE CARD32 +#endif + int srcwidth = pCurs->bits->width; + int srcheight = pCurs->bits->height; + CARD32 temp, status1 = 0, status2 = 0; + BOOLEAN sizedouble = FALSE; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef SISMERGED + if(pSiS->MergedFB) { + if((CDMPTR->CRT1->Flags & V_DBLSCAN) && (CDMPTR->CRT2->Flags & V_DBLSCAN)) { + sizedouble = TRUE; + } + } else +#endif + if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { + sizedouble = TRUE; + } + + cursor_addr = pScrn->videoRam - pSiS->cursorOffset - ((pSiS->CursorSize/1024) * 2); + + if(srcwidth > 32) srcwidth = 32; + if(srcheight > 32) srcheight = 32; + +#ifdef SISDUALHEAD + if (pSiS->DualHeadMode) + /* TW: Use the global (real) FbBase in DHM */ + dest = (MYSISPTRTYPE *)((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024)); + else +#endif + dest = (MYSISPTRTYPE *)((unsigned char *)pSiS->FbBase + (cursor_addr * 1024)); + + if(sizedouble) { + if(srcheight > 16) srcheight = 16; + maxheight = 16; + } + +#ifdef SIS300_USE_ARGB16 /* Use 16 Bit RGB pointer */ + for(i = 0; i < srcheight; i++) { + p = src; + pb = dest; + src += pCurs->bits->width; + for(j = 0; j < srcwidth; j++) { + temp = *p++; + if(temp & 0xffffff) { + temp1 = ((temp & 0xff) >> 3) | + ((((temp & 0xff00) >> (8 + 3)) << 5) & 0x03e0) | + ((((temp & 0xff0000) >> (16 + 3)) << 10) & 0x7c00); + } else temp1 = 0x8000; + *dest++ = temp1; + } + if(srcwidth < 32) { + for(; j < 32; j++) { + *dest++ = 0x8000; + } + } + } + if(srcheight < maxheight) { + for(; i < maxheight; i++) + for(j = 0; j < 32; j++) { + *dest++ = 0x8000; + } + if(sizedouble) { + for(j = 0; j < 32; j++) + *dest++ = 0x0000; + } + } +#else /* Use 32bit RGB pointer - preferred, saves us from the conversion */ + for(i = 0; i < srcheight; i++) { + p = src; + pb = dest; + src += pCurs->bits->width; + for(j = 0; j < srcwidth; j++) { + temp = *p++; +/* *dest1++ = ((temp ^ 0xff000000) << 4) | (((temp ^ 0xff000000) & 0xf0000000) >> 28); */ + if(pSiS->OptUseColorCursorBlend) { + if(temp & 0xffffff) { + if((temp & 0xff000000) > pSiS->OptColorCursorBlendThreshold) { + temp &= 0x00ffffff; + } else { + temp = 0xff111111; + } + } else temp = 0xff000000; + } else { + if(temp & 0xffffff) temp &= 0x00ffffff; + else temp = 0xff000000; + } + *dest++ = temp; + } + if(srcwidth < 32) { + for(; j < 32; j++) { + *dest++ = 0xff000000; + } + } + if(sizedouble) { + for(j = 0; j < 32; j++) { + *dest++ = *pb++; + } + } + + } + if(srcheight < maxheight) { + for(; i < maxheight; i++) { + for(j = 0; j < 32; j++) { + *dest++ = 0xff000000; + } + if(sizedouble) { + for(j = 0; j < 32; j++) { + *dest++ = 0xff000000; + } + } } + } +#endif + + if(!pSiS->UseHWARGBCursor) { + if(pSiS->VBFlags & DISPTYPE_CRT1) { + status1 = sis300GetCursorStatus; + sis300DisableHWCursor() + if(pSiS->VBFlags & CRT2_ENABLE) { + status2 = sis301GetCursorStatus; + sis301DisableHWCursor() + } + SISWaitRetraceCRT1(pScrn); + sis300SwitchToRGBCursor(); + if(pSiS->VBFlags & CRT2_ENABLE) { + SISWaitRetraceCRT2(pScrn); + sis301SwitchToRGBCursor(); + } + } + } + sis300SetCursorAddress(cursor_addr); + sis300SetCursorPatternSelect(0); + if(status1) sis300SetCursorStatus(status1) + + if(pSiS->VBFlags & CRT2_ENABLE) { + if((!pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) { + status2 = sis301GetCursorStatus; + sis301DisableHWCursor() + SISWaitRetraceCRT2(pScrn); + sis301SwitchToRGBCursor(); + } + sis301SetCursorAddress(cursor_addr) + sis301SetCursorPatternSelect(0) + if(status2) sis301SetCursorStatus(status2) + } + + pSiS->UseHWARGBCursor = TRUE; +} - return mem; +static void SiS310LoadCursorImageARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) +{ + SISPtr pSiS = SISPTR(pScrn); + int cursor_addr, i, j, maxheight = 64; + CARD32 *src = pCurs->bits->argb, *p, *pb, *dest; + int srcwidth = pCurs->bits->width; + int srcheight = pCurs->bits->height; + CARD32 status1 = 0, status2 = 0; + BOOLEAN sizedouble = FALSE; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef SISMERGED + if(pSiS->MergedFB) { + if((CDMPTR->CRT1->Flags & V_DBLSCAN) && (CDMPTR->CRT2->Flags & V_DBLSCAN)) { + sizedouble = TRUE; + } + } else +#endif + if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { + sizedouble = TRUE; + } + + cursor_addr = pScrn->videoRam - pSiS->cursorOffset - ((pSiS->CursorSize/1024) * 2); + + if(srcwidth > 64) srcwidth = 64; + if(srcheight > 64) srcheight = 64; + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) + /* TW: Use the global (real) FbBase in DHM */ + dest = (CARD32 *)((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024)); + else +#endif + dest = (CARD32 *)((unsigned char *)pSiS->FbBase + (cursor_addr * 1024)); + + if(sizedouble) { + if(srcheight > 32) srcheight = 32; + maxheight = 32; + } + + for(i = 0; i < srcheight; i++) { + p = src; + pb = dest; + src += pCurs->bits->width; + for(j = 0; j < srcwidth; j++) *dest++ = *p++; + if(srcwidth < 64) { + for(; j < 64; j++) *dest++ = 0; + } + if(sizedouble) { + for(j = 0; j < 64; j++) { + *dest++ = *pb++; + } + } + } + if(srcheight < maxheight) { + for(; i < maxheight; i++) + for(j = 0; j < 64; j++) *dest++ = 0; + if(sizedouble) { + for(j = 0; j < 64; j++) *dest++ = 0; + } + } + + if(pSiS->ChipFlags & SiSCF_XabreCore) { + + if(!pSiS->UseHWARGBCursor) { + if(pSiS->VBFlags & DISPTYPE_CRT1) { + status1 = sis310GetCursorStatus; + sis310DisableHWCursor() + } + SISWaitRetraceCRT1(pScrn); + sis310SwitchToRGBCursor(); + } + + } else { + + if(!pSiS->UseHWARGBCursor) { + if(pSiS->VBFlags & DISPTYPE_CRT1) { + status1 = sis310GetCursorStatus; + sis310DisableHWCursor() + if(pSiS->VBFlags & CRT2_ENABLE) { + status2 = sis301GetCursorStatus310; + sis301DisableHWCursor310() + } + } + SISWaitRetraceCRT1(pScrn); + sis310SwitchToRGBCursor(); + if(pSiS->VBFlags & CRT2_ENABLE) { + SISWaitRetraceCRT2(pScrn); + sis301SwitchToRGBCursor310(); + } + } + } + + sis310SetCursorAddress(cursor_addr); + sis310SetCursorPatternSelect(0); + if(status1) sis310SetCursorStatus(status1) + + if(pSiS->VBFlags & CRT2_ENABLE) { + if(pSiS->ChipFlags & SiSCF_XabreCore) { + sis301SetCursorAddress330(cursor_addr) + sis301SetCursorPatternSelect330(0) + } else { + if((!pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) { + status2 = sis301GetCursorStatus310; + sis301DisableHWCursor310() + SISWaitRetraceCRT2(pScrn); + sis301SwitchToRGBCursor310(); + } + sis301SetCursorAddress310(cursor_addr) + sis301SetCursorPatternSelect310(0) + if(status2) sis301SetCursorStatus310(status2) + } + } + + pSiS->UseHWARGBCursor = TRUE; } #endif +#endif +#endif Bool SiSHWCursorInit(ScreenPtr pScreen) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSiS = SISPTR(pScrn); - xf86CursorInfoPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + xf86CursorInfoPtr infoPtr; - PDEBUG(ErrorF("HW Cursor Init\n")); - infoPtr = xf86CreateCursorInfoRec(); - if(!infoPtr) return FALSE; + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; - pSiS->CursorInfoPtr = infoPtr; + pSiS->CursorInfoPtr = infoPtr; + pSiS->UseHWARGBCursor = FALSE; - infoPtr->MaxWidth = 64; - infoPtr->MaxHeight = 64; - switch (pSiS->Chipset) { - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - infoPtr->ShowCursor = SiS300ShowCursor; - infoPtr->HideCursor = SiS300HideCursor; - infoPtr->SetCursorPosition = SiS300SetCursorPosition; - infoPtr->SetCursorColors = SiS300SetCursorColors; - infoPtr->LoadCursorImage = SiS300LoadCursorImage; - infoPtr->UseHWCursor = SiS300UseHWCursor; - infoPtr->Flags = - HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_INVERT_MASK | - HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | - HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | - HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; - break; - default: - infoPtr->SetCursorPosition = SiSSetCursorPosition; - infoPtr->ShowCursor = SiSShowCursor; - infoPtr->HideCursor = SiSHideCursor; - infoPtr->SetCursorColors = SiSSetCursorColors; - infoPtr->LoadCursorImage = SiSLoadCursorImage; - infoPtr->UseHWCursor = SiSUseHWCursor; - infoPtr->Flags = - HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_INVERT_MASK | - HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | - HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | - HARDWARE_CURSOR_NIBBLE_SWAPPED | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; - break; + switch (pSiS->Chipset) { + + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS540: + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->ShowCursor = SiS300ShowCursor; + infoPtr->HideCursor = SiS300HideCursor; + infoPtr->SetCursorPosition = SiS300SetCursorPosition; + infoPtr->SetCursorColors = SiS300SetCursorColors; + infoPtr->LoadCursorImage = SiS300LoadCursorImage; + infoPtr->UseHWCursor = SiS300UseHWCursor; +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) +#ifdef ARGB_CURSOR +#ifdef SIS_ARGB_CURSOR + if(pSiS->OptUseColorCursor) { + infoPtr->UseHWCursorARGB = SiSUseHWCursorARGB; + infoPtr->LoadCursorARGB = SiS300LoadCursorImageARGB; } +#endif +#endif +#endif + infoPtr->Flags = + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; + break; - return(xf86InitCursor(pScreen, infoPtr)); -} + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->ShowCursor = SiS310ShowCursor; + infoPtr->HideCursor = SiS310HideCursor; + infoPtr->SetCursorPosition = SiS310SetCursorPosition; + infoPtr->SetCursorColors = SiS310SetCursorColors; + infoPtr->LoadCursorImage = SiS310LoadCursorImage; + infoPtr->UseHWCursor = SiS300UseHWCursor; +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) +#ifdef ARGB_CURSOR +#ifdef SIS_ARGB_CURSOR + if(pSiS->OptUseColorCursor) { + infoPtr->UseHWCursorARGB = SiSUseHWCursorARGB; + infoPtr->LoadCursorARGB = SiS310LoadCursorImageARGB; + } +#endif +#endif +#endif + infoPtr->Flags = + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; + break; + default: + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->SetCursorPosition = SiSSetCursorPosition; + infoPtr->ShowCursor = SiSShowCursor; + infoPtr->HideCursor = SiSHideCursor; + infoPtr->SetCursorColors = SiSSetCursorColors; + infoPtr->LoadCursorImage = SiSLoadCursorImage; + infoPtr->UseHWCursor = SiSUseHWCursor; + infoPtr->Flags = + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_NIBBLE_SWAPPED | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; + break; + } + + return(xf86InitCursor(pScreen, infoPtr)); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.h index 30d8b8eb9..4d62cf367 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.h @@ -1,78 +1,506 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.h,v 1.9 2003/06/26 22:35:17 twini Exp $ */ /* + * SiS hardware cursor handling + * Definitions + * * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holders not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. + * Thomas Winischhofer <thomas@winischhofer.net>: + */ + +#define CS(x) (0x8500+(x<<2)) + +/* 300 series, CRT1 */ + +/* 80000000 = RGB(1) - MONO(0) + * 40000000 = enable(1) - disable(0) + * 20000000 = 32(1) / 16(1) bit RGB + * 10000000 = "ghost"(1) - [other effect](0) */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.h,v 1.1 2000/02/12 20:45:34 dawes Exp $ */ -#define CS(x) (0x8500+(x<<2)) +#define sis300GetCursorStatus \ + MMIO_IN32(pSiS->IOBase, CS(0)) & 0x40000000; + +#define sis300SetCursorStatus(status) \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xbfffffff; \ + temp |= status; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis300EnableHWCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0x0fffffff; \ + temp |= 0x40000000; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis300EnableHWARGBCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp |= 0xF0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } -#define sis300EnableHWCursor()\ - *(volatile CARD32 *)(pSiS->IOBase + CS(0)) |= 0x40000000; +#define sis300EnableHWARGB16Cursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0x0fffffff; \ + temp |= 0xD0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis300SwitchToMONOCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0x4fffffff; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis300SwitchToRGBCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp |= 0xB0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + #define sis300DisableHWCursor()\ - *(volatile CARD32 *)(pSiS->IOBase + CS(0)) &= 0x3FFFFFFF; + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xbFFFFFFF; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } #define sis300SetCursorBGColor(color)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(1)) = (color); + MMIO_OUT32(pSiS->IOBase, CS(1), (color)); #define sis300SetCursorFGColor(color)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(2)) = (color); + MMIO_OUT32(pSiS->IOBase, CS(2), (color)); #define sis300SetCursorPositionX(x,preset)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(3)) = (x) | ((preset) << 16); + MMIO_OUT32(pSiS->IOBase, CS(3), ((x) | ((preset) << 16))); #define sis300SetCursorPositionY(y,preset)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(4)) = (y) | ((preset) << 16); + MMIO_OUT32(pSiS->IOBase, CS(4), ((y) | ((preset) << 16))); #define sis300SetCursorAddress(address)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(0)) &= 0xFFFF0000;\ - *(volatile CARD32 *)(pSiS->IOBase + CS(0)) |= address; + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xFFFF0000; \ + temp |= address; \ + MMIO_OUT32(pSiS->IOBase,CS(0),temp); \ + } #define sis300SetCursorPatternSelect(pat_id)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(0)) &= 0xF0FFFFFF;\ - *(volatile CARD32 *)(pSiS->IOBase + CS(0)) |= ((pat_id) << 24); + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xF0FFFFFF; \ + temp |= (pat_id) << 24; \ + MMIO_OUT32(pSiS->IOBase,CS(0),temp); \ + } +/* 300 series, CRT2 */ +/* 80000000 = RGB(1) - MONO(0) + * 40000000 = enable(1) - disable(0) + * 20000000 = 32(1) / 16(1) bit RGB + * 10000000 = unused (always "ghosting") + */ +#define sis301GetCursorStatus \ + MMIO_IN32(pSiS->IOBase, CS(8)) & 0x40000000; + +#define sis301SetCursorStatus(status) \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xbfffffff; \ + temp |= status; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + #define sis301EnableHWCursor()\ - *(volatile CARD32 *)(pSiS->IOBase + CS(8)) |= 0x40000000; + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0x0fffffff; \ + temp |= 0x40000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301EnableHWARGBCursor()\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp |= 0xF0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301EnableHWARGB16Cursor()\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0x0FFFFFFF; \ + temp |= 0xD0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301SwitchToRGBCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp |= 0xB0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301SwitchToMONOCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0x4fffffff; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + #define sis301DisableHWCursor()\ - *(volatile CARD32 *)(pSiS->IOBase + CS(8)) &= 0xBFFFFFFF; - + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xbFFFFFFF; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + #define sis301SetCursorBGColor(color)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(9)) = (color); + MMIO_OUT32(pSiS->IOBase, CS(9), (color)); #define sis301SetCursorFGColor(color)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(10)) = (color); + MMIO_OUT32(pSiS->IOBase, CS(10), (color)); #define sis301SetCursorPositionX(x,preset)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(11)) = (x) | ((preset) << 16); + MMIO_OUT32(pSiS->IOBase, CS(11), ((x) | ((preset) << 16))); #define sis301SetCursorPositionY(y,preset)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(12)) = (y) | ((preset) << 16); + MMIO_OUT32(pSiS->IOBase, CS(12), ((y) | ((preset) << 16))); #define sis301SetCursorAddress(address)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(8)) &= 0xFFFF0000;\ - *(volatile CARD32 *)(pSiS->IOBase + CS(8)) |= address; + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xFFFF0000; \ + temp |= address; \ + MMIO_OUT32(pSiS->IOBase,CS(8),temp); \ + } #define sis301SetCursorPatternSelect(pat_id)\ - *(volatile CARD32 *)(pSiS->IOBase + CS(8)) &= 0xF0FFFFFF;\ - *(volatile CARD32 *)(pSiS->IOBase + CS(8)) |= ((pat_id) << 24); + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xF0FFFFFF; \ + temp |= (pat_id) << 24; \ + MMIO_OUT32(pSiS->IOBase,CS(8),temp); \ + } + +/* 315/330 series CRT1 */ + +/* 80000000 = RGB(1) - MONO(0) + * 40000000 = enable(1) - disable(0) + * 20000000 = 32(1) / 16(1) bit RGB + * 10000000 = "ghost"(1) - Alpha Blend(0) + */ + +#define sis310GetCursorStatus \ + MMIO_IN32(pSiS->IOBase, CS(0)) & 0x40000000; + +#define sis310SetCursorStatus(status) \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xbfffffff; \ + temp |= status; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis310EnableHWCursor()\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0x0fffffff; \ + temp |= 0x40000000; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis310EnableHWARGBCursor()\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0x0FFFFFFF; \ + temp |= 0xE0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis310SwitchToMONOCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0x4fffffff; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis310SwitchToRGBCursor() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xBFFFFFFF; \ + temp |= 0xA0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis310DisableHWCursor()\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xBFFFFFFF; \ + MMIO_OUT32(pSiS->IOBase, CS(0), temp); \ + } + +#define sis310SetCursorBGColor(color) \ + MMIO_OUT32(pSiS->IOBase, CS(1), (color)); + +#define sis310SetCursorFGColor(color)\ + MMIO_OUT32(pSiS->IOBase, CS(2), (color)); + +#define sis310SetCursorPositionX(x,preset)\ + MMIO_OUT32(pSiS->IOBase, CS(3), ((x) | ((preset) << 16))); + +#define sis310SetCursorPositionY(y,preset)\ + MMIO_OUT32(pSiS->IOBase, CS(4), ((y) | ((preset) << 16))); + +#define sis310SetCursorAddress(address)\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xFFF00000; \ + temp |= address; \ + MMIO_OUT32(pSiS->IOBase,CS(0),temp); \ + } + +#define sis310SetCursorPatternSelect(pat_id)\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(0)); \ + temp &= 0xF0FFFFFF; \ + temp |= (pat_id) << 24; \ + MMIO_OUT32(pSiS->IOBase,CS(0),temp); \ + } + +/* 315 series CRT2 */ + +/* 80000000 = RGB(1) - MONO(0) + * 40000000 = enable(1) - disable(0) + * 20000000 = 32(1) / 16(1) bit RGB + * 10000000 = "ghost"(1) - Alpha Blend(0) ? + */ + +#define sis301GetCursorStatus310 \ + MMIO_IN32(pSiS->IOBase, CS(8)) & 0x40000000; + +#define sis301SetCursorStatus310(status) \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xbfffffff; \ + temp |= status; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301EnableHWCursor310()\ + { \ + unsigned long temp, temp1, temp2; \ + temp1 = MMIO_IN32(pSiS->IOBase, CS(11)); \ + temp2 = MMIO_IN32(pSiS->IOBase, CS(12)); \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0x0fffffff; \ + temp |= 0x40000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + MMIO_OUT32(pSiS->IOBase, CS(11), temp1); \ + MMIO_OUT32(pSiS->IOBase, CS(12), temp2); \ + } + +#define sis301EnableHWARGBCursor310()\ + { \ + unsigned long temp, temp1, temp2; \ + temp1 = MMIO_IN32(pSiS->IOBase, CS(11)); \ + temp2 = MMIO_IN32(pSiS->IOBase, CS(12)); \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0x0FFFFFFF; \ + temp |= 0xE0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + MMIO_OUT32(pSiS->IOBase, CS(11), temp1); \ + MMIO_OUT32(pSiS->IOBase, CS(12), temp2); \ + } + +#define sis301SwitchToRGBCursor310() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xBFFFFFFF; \ + temp |= 0xA0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301SwitchToMONOCursor310() \ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0x4fffffff; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301DisableHWCursor310()\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xBFFFFFFF; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + } + +#define sis301SetCursorBGColor310(color)\ + MMIO_OUT32(pSiS->IOBase, CS(9), (color)); +#define sis301SetCursorFGColor310(color)\ + MMIO_OUT32(pSiS->IOBase, CS(10), (color)); + +#define sis301SetCursorPositionX310(x,preset)\ + MMIO_OUT32(pSiS->IOBase, CS(11), ((x) | ((preset) << 16))); +#define sis301SetCursorPositionY310(y,preset)\ + MMIO_OUT32(pSiS->IOBase, CS(12), ((y) | ((preset) << 16))); + +#define sis301SetCursorAddress310(address)\ + { \ + unsigned long temp; \ + if(pSiS->sishw_ext.jChipType == SIS_315H) { \ + if(address & 0x10000) { \ + address &= ~0x10000; \ + orSISIDXREG(SISSR, 0x37, 0x80); \ + } else { \ + andSISIDXREG(SISSR, 0x37, 0x7f); \ + } \ + } \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xFFF00000; \ + temp |= address; \ + MMIO_OUT32(pSiS->IOBase,CS(8),temp); \ + } + +#define sis301SetCursorPatternSelect310(pat_id)\ + { \ + unsigned long temp; \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xF0FFFFFF; \ + temp |= (pat_id) << 24; \ + MMIO_OUT32(pSiS->IOBase,CS(8),temp); \ + } + +/* 330 series CRT2 */ + +/* Mono cursor engine for CRt2 on 330 has bugs and cannot be + * used! + */ + +/* 80000000 = RGB(1) - MONO(0) + * 40000000 = enable(1) - disable(0) + * 20000000 = 32(1) / 16(1) bit RGB + * 10000000 = "ghost"(1) - Alpha Blend(0) ? + */ + +#define sis301EnableHWCursor330()\ + { \ + unsigned long temp, temp1, temp2; \ + andSISIDXREG(SISCR,0x5b,~0x10); \ + temp1 = MMIO_IN32(pSiS->IOBase, CS(11)); \ + temp2 = MMIO_IN32(pSiS->IOBase, CS(12)); \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0x0fffffff; \ + temp |= 0xE0000000; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + MMIO_OUT32(pSiS->IOBase, CS(11), temp1); \ + MMIO_OUT32(pSiS->IOBase, CS(12), temp2); \ + orSISIDXREG(SISCR,0x5b,0x10); \ + } + +#define sis301DisableHWCursor330()\ + { \ + unsigned long temp; \ + andSISIDXREG(SISCR,0x5b,~0x10); \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xBFFFFFFF; \ + MMIO_OUT32(pSiS->IOBase, CS(8), temp); \ + orSISIDXREG(SISCR,0x5b,0x10); \ + } + +#define sis301SetCursorPositionX330(x,preset)\ + andSISIDXREG(SISCR,0x5b,~0x10); \ + MMIO_OUT32(pSiS->IOBase, CS(11), ((x) | ((preset) << 16))); \ + orSISIDXREG(SISCR,0x5b,0x10); + +#define sis301SetCursorPositionY330(y,preset)\ + andSISIDXREG(SISCR,0x5b,~0x10); \ + MMIO_OUT32(pSiS->IOBase, CS(12), ((y) | ((preset) << 16))); \ + orSISIDXREG(SISCR,0x5b,0x10); \ + +#define sis301SetCursorAddress330(address)\ + { \ + unsigned long temp, temp1, temp2; \ + temp1 = MMIO_IN32(pSiS->IOBase, CS(11)); \ + temp2 = MMIO_IN32(pSiS->IOBase, CS(12)); \ + andSISIDXREG(SISCR,0x5b,~0x10); \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xFFF00000; \ + temp |= address; \ + MMIO_OUT32(pSiS->IOBase,CS(8),temp); \ + MMIO_OUT32(pSiS->IOBase, CS(11), temp1); \ + MMIO_OUT32(pSiS->IOBase, CS(12), temp2); \ + orSISIDXREG(SISCR,0x5b,0x10); \ + } + +#define sis301SetCursorPatternSelect330(pat_id)\ + { \ + unsigned long temp; \ + andSISIDXREG(SISCR,0x5b,~0x10); \ + temp = MMIO_IN32(pSiS->IOBase, CS(8)); \ + temp &= 0xF0FFFFFF; \ + temp |= (pat_id) << 24; \ + MMIO_OUT32(pSiS->IOBase,CS(8),temp); \ + orSISIDXREG(SISCR,0x5b,0x10); \ + } + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c index 5d0054bef..593aeb782 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c @@ -1,31 +1,37 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c,v 1.37 2003/08/07 12:52:23 twini Exp $ */ /* - * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * DAC helper functions (Save/Restore, MemClk, etc) + * + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. + * Parts Copyright 1998,1999 by Alan Hourihane, Wigan, England. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the provider not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The provider makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE PROVIDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE PROVIDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * MemClock functions by: + * Alan Hourihane <alanh@fairlite.demon.co.uk> + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c,v 1.11 1999/07/06 11:38:45 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -33,702 +39,2021 @@ #include "xf86Version.h" #include "xf86PciInfo.h" #include "xf86Pci.h" - -#include "vgaHW.h" +#include "xf86DDC.h" #include "sis.h" +#include "sis_dac.h" #include "sis_regs.h" +#include "sis_vb.h" + +static void SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); + +static void SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS301Save(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS301BSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS301LoadPalette(ScrnInfoPtr pScrn, int numColors, + int *indicies, LOCO *colors, VisualPtr pVisual); +static void SiSThreshold(ScrnInfoPtr pScrn, DisplayModePtr mode, + unsigned short *Low, unsigned short *High); +static void SetBlock(CARD16 port, CARD8 from, CARD8 to, CARD8 *DataPtr); + +static const unsigned short ch700xidx[] = { + 0x00,0x07,0x08,0x0a,0x0b,0x04,0x09,0x20,0x21,0x18,0x19,0x1a, + 0x1b,0x1c,0x1d,0x1e,0x1f, /* 0x0e, - TW: Don't save the power register */ + 0x01,0x03,0x06,0x0d,0x11,0x13,0x14,0x15,0x17,0x22,0x23,0x24 + }; + +static const unsigned short ch701xidx[] = { + 0x1c,0x5f,0x64,0x6f,0x70,0x71,0x72,0x73,0x74,0x76,0x78,0x7d, + 0x67,0x68,0x69,0x6a,0x6b,0x1e,0x00,0x01,0x02,0x04,0x03,0x05, + 0x06,0x07,0x08,0x15,0x1f,0x0c,0x0d,0x0e,0x0f,0x10,0x66 + }; + +int SiS_compute_vclk( + int Clock, + int *out_n, + int *out_dn, + int *out_div, + int *out_sbit, + int *out_scale) +{ + float f,x,y,t, error, min_error; + int n, dn, best_n=0, best_dn=0; -static void + /* + * Rules + * + * VCLK = 14.318 * (Divider/Post Scalar) * (Numerator/DeNumerator) + * Factor = (Divider/Post Scalar) + * Divider is 1 or 2 + * Post Scalar is 1, 2, 3, 4, 6 or 8 + * Numberator ranged from 1 to 128 + * DeNumerator ranged from 1 to 32 + * a. VCO = VCLK/Factor, suggest range is 150 to 250 Mhz + * b. Post Scalar selected from 1, 2, 4 or 8 first. + * c. DeNumerator selected from 2. + * + * According to rule a and b, the VCO ranges that can be scaled by + * rule b are: + * 150 - 250 (Factor = 1) + * 75 - 125 (Factor = 2) + * 37.5 - 62.5 (Factor = 4) + * 18.75 - 31.25 (Factor = 8) + * + * The following ranges use Post Scalar 3 or 6: + * 125 - 150 (Factor = 1.5) + * 62.5 - 75 (Factor = 3) + * 31.25 - 37.5 (Factor = 6) + * + * Steps: + * 1. divide the Clock by 2 until the Clock is less or equal to 31.25. + * 2. if the divided Clock is range from 18.25 to 31.25, than + * the Factor is 1, 2, 4 or 8. + * 3. if the divided Clock is range from 15.625 to 18.25, than + * the Factor is 1.5, 3 or 6. + * 4. select the Numberator and DeNumberator with minimum deviation. + * + * ** this function can select VCLK ranged from 18.75 to 250 Mhz + */ + + f = (float) Clock; + f /= 1000.0; + if((f > 250.0) || (f < 18.75)) + return 0; + + min_error = f; + y = 1.0; + x = f; + while(x > 31.25) { + y *= 2.0; + x /= 2.0; + } + if(x >= 18.25) { + x *= 8.0; + y = 8.0 / y; + } else if(x >= 15.625) { + x *= 12.0; + y = 12.0 / y; + } + + t = y; + if(t == (float) 1.5) { + *out_div = 2; + t *= 2.0; + } else { + *out_div = 1; + } + if(t > (float) 4.0) { + *out_sbit = 1; + t /= 2.0; + } else { + *out_sbit = 0; + } + + *out_scale = (int) t; + + for(dn = 2; dn <= 32; dn++) { + for(n = 1; n <= 128; n++) { + error = x; + error -= ((float) 14.318 * (float) n / (float) dn); + if(error < (float) 0) + error = -error; + if(error < min_error) { + min_error = error; + best_n = n; + best_dn = dn; + } + } + } + *out_n = best_n; + *out_dn = best_dn; + PDEBUG(ErrorF("SiS_compute_vclk: Clock=%d, n=%d, dn=%d, div=%d, sbit=%d," + " scale=%d\n", Clock, best_n, best_dn, *out_div, + *out_sbit, *out_scale)); + return 1; +} + + +void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk) { SISPtr pSiS = SISPTR(pScrn); int M, N, P , PSN, VLD , PSNx ; - int bestM, bestN, bestP, bestPSN, bestVLD; + int bestM=0, bestN=0, bestP=0, bestPSN=0, bestVLD=0; double bestError, abest = 42.0, bestFout; double target; double Fvco, Fout; double error, aerror; /* - * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler) + * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler) * - * M = Numerator [1:128] - * N = DeNumerator [1:32] - * VLD = Divider (Vco Loop Divider) : divide by 1, 2 - * P = Post Scaler : divide by 1, 2, 3, 4 + * M = Numerator [1:128] + * N = DeNumerator [1:32] + * VLD = Divider (Vco Loop Divider) : divide by 1, 2 + * P = Post Scaler : divide by 1, 2, 3, 4 * PSN = Pre Scaler (Reference Divisor Select) * * result in vclk[] */ -#define Midx 0 -#define Nidx 1 -#define VLDidx 2 -#define Pidx 3 -#define PSNidx 4 +#define Midx 0 +#define Nidx 1 +#define VLDidx 2 +#define Pidx 3 +#define PSNidx 4 #define Fref 14318180 /* stability constraints for internal VCO -- MAX_VCO also determines * the maximum Video pixel clock */ -#define MIN_VCO Fref -#define MAX_VCO 135000000 +#define MIN_VCO Fref +#define MAX_VCO 135000000 #define MAX_VCO_5597 353000000 -#define MAX_PSN 0 /* no pre scaler for this chip */ -#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */ +#define MAX_PSN 0 /* no pre scaler for this chip */ +#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */ - int M_min = 2; + int M_min = 2; int M_max = 128; - -/* abest=10000.0; */ - + target = clock * 1000; - - - if (pSiS->Chipset == PCI_CHIP_SIS5597 || pSiS->Chipset == PCI_CHIP_SIS6326){ - int low_N = 2; - int high_N = 5; - int PSN = 1; - - P = 1; - if (target < MAX_VCO_5597 / 2) - P = 2; - if (target < MAX_VCO_5597 / 3) - P = 3; - if (target < MAX_VCO_5597 / 4) - P = 4; - if (target < MAX_VCO_5597 / 6) - P = 6; - if (target < MAX_VCO_5597 / 8) - P = 8; - - Fvco = P * target; - - for (N = low_N; N <= high_N; N++){ - double M_desired = Fvco / Fref * N; - if (M_desired > M_max * max_VLD) - continue; - - if ( M_desired > M_max ) { - M = M_desired / 2 + 0.5; - VLD = 2; - } else { - M = Fvco / Fref * N + 0.5; - VLD = 1; - } - - Fout = (double)Fref * (M * VLD)/(N * P); - - error = (target - Fout) / target; - aerror = (error < 0) ? -error : error; -/* if (aerror < abest && abest > TOLERANCE) {*/ - if (aerror < abest) { - abest = aerror; - bestError = error; - bestM = M; - bestN = N; - bestP = P; - bestPSN = PSN; - bestVLD = VLD; - bestFout = Fout; - } - } - } - else { - for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { - int low_N, high_N; - double FrefVLDPSN; - - PSN = !PSNx ? 1 : 4; - - low_N = 2; - high_N = 32; - - for ( VLD = 1 ; VLD <= max_VLD ; VLD++ ) { - - FrefVLDPSN = (double)Fref * VLD / PSN; - for (N = low_N; N <= high_N; N++) { - double tmp = FrefVLDPSN / N; - - for (P = 1; P <= 4; P++) { - double Fvco_desired = target * ( P ); - double M_desired = Fvco_desired / tmp; - - /* Which way will M_desired be rounded? - * Do all three just to be safe. - */ - int M_low = M_desired - 1; - int M_hi = M_desired + 1; - - if (M_hi < M_min || M_low > M_max) - continue; - - if (M_low < M_min) - M_low = M_min; - if (M_hi > M_max) - M_hi = M_max; - - for (M = M_low; M <= M_hi; M++) { - Fvco = tmp * M; - if (Fvco <= MIN_VCO) - continue; - if (Fvco > MAX_VCO) - break; - - Fout = Fvco / ( P ); - - error = (target - Fout) / target; - aerror = (error < 0) ? -error : error; - if (aerror < abest) { - abest = aerror; - bestError = error; - bestM = M; - bestN = N; - bestP = P; - bestPSN = PSN; - bestVLD = VLD; - bestFout = Fout; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d," - " P=%d, PSN=%d\n", - (float)(clock / 1000.), M, N, P, VLD, PSN); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. set: %.2f MHz\n", Fout / 1.0e6); - } - } - } - } + + if(pSiS->Chipset == PCI_CHIP_SIS5597 || pSiS->Chipset == PCI_CHIP_SIS6326) { + + int low_N = 2; + int high_N = 5; + + PSN = 1; + P = 1; + if(target < MAX_VCO_5597 / 2) P = 2; + if(target < MAX_VCO_5597 / 3) P = 3; + if(target < MAX_VCO_5597 / 4) P = 4; + if(target < MAX_VCO_5597 / 6) P = 6; + if(target < MAX_VCO_5597 / 8) P = 8; + + Fvco = P * target; + + for(N = low_N; N <= high_N; N++) { + + double M_desired = Fvco / Fref * N; + if(M_desired > M_max * max_VLD) continue; + + if(M_desired > M_max) { + M = M_desired / 2 + 0.5; + VLD = 2; + } else { + M = Fvco / Fref * N + 0.5; + VLD = 1; + } + + Fout = (double)Fref * (M * VLD)/(N * P); + + error = (target - Fout) / target; + aerror = (error < 0) ? -error : error; + if(aerror < abest) { + abest = aerror; + bestError = error; + bestM = M; + bestN = N; + bestP = P; + bestPSN = PSN; + bestVLD = VLD; + bestFout = Fout; } + } + + } else { + + for(PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { + + int low_N, high_N; + double FrefVLDPSN; + + PSN = !PSNx ? 1 : 4; + + low_N = 2; + high_N = 32; + + for(VLD = 1 ; VLD <= max_VLD ; VLD++) { + + FrefVLDPSN = (double)Fref * VLD / PSN; + + for(N = low_N; N <= high_N; N++) { + double tmp = FrefVLDPSN / N; + + for(P = 1; P <= 4; P++) { + double Fvco_desired = target * ( P ); + double M_desired = Fvco_desired / tmp; + + /* Which way will M_desired be rounded? + * Do all three just to be safe. + */ + int M_low = M_desired - 1; + int M_hi = M_desired + 1; + + if(M_hi < M_min || M_low > M_max) continue; + + if(M_low < M_min) M_low = M_min; + + if(M_hi > M_max) M_hi = M_max; + + for(M = M_low; M <= M_hi; M++) { + Fvco = tmp * M; + if(Fvco <= MIN_VCO) continue; + if(Fvco > MAX_VCO) break; + + Fout = Fvco / ( P ); + + error = (target - Fout) / target; + aerror = (error < 0) ? -error : error; + if(aerror < abest) { + abest = aerror; + bestError = error; + bestM = M; + bestN = N; + bestP = P; + bestPSN = PSN; + bestVLD = VLD; + bestFout = Fout; + } +#ifdef TWDEBUG + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3, + "Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", + (float)(clock / 1000.), M, N, P, VLD, PSN); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3, + "Freq. set: %.2f MHz\n", Fout / 1.0e6); +#endif + } + } + } + } + } } - vclk[Midx] = bestM; - vclk[Nidx] = bestN; - vclk[VLDidx] = bestVLD; - vclk[Pidx] = bestP; - vclk[PSNidx] = bestPSN; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", - (float)(clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx], - vclk[Pidx], vclk[PSNidx]); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. set: %.2f MHz\n", bestFout / 1.0e6); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"VCO Freq.: %.2f MHz\n", bestFout*bestP / 1.0e6); + vclk[Midx] = bestM; + vclk[Nidx] = bestN; + vclk[VLDidx] = bestVLD; + vclk[Pidx] = bestP; + vclk[PSNidx] = bestPSN; + + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", + (float)(clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx], + vclk[Pidx], vclk[PSNidx])); + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Freq. set: %.2f MHz\n", bestFout / 1.0e6)); + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "VCO Freq.: %.2f MHz\n", bestFout*bestP / 1.0e6)); } -Bool -SiSInit(ScrnInfoPtr pScrn, DisplayModePtr mode) + +static void +SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); - SISRegPtr pReg = &pSiS->ModeReg; - int gap, safetymargin, MemBand; - int vgaIOBase; - unsigned char temp; -#if 1 - int Base,mclk; -#endif - int offset; - int clock = mode->Clock; - unsigned int vclk[5]; - unsigned int CRT_CPUthresholdLow ; - unsigned int CRT_CPUthresholdHigh ; - unsigned int CRT_ENGthreshold ; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"SiSInit()\n"); - vgaHWGetIOBase(VGAHWPTR(pScrn)); - vgaIOBase = VGAHWPTR(pScrn)->IOBase; - - offset = pScrn->displayWidth >> (mode->Flags & V_INTERLACE ? 2 : 3); - - SiSSave(pScrn, pReg); - - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); - - pReg->sisRegs3C4[BankReg] |= 0x82; /* Enable Linear */ - - switch (pScrn->depth) { - case 8: - break; - case 15: - offset <<= 1; - pReg->sisRegs3C4[BankReg] |= 0x04; - break; - case 16: - offset <<= 1; - pReg->sisRegs3C4[BankReg] |= 0x08; - break; - case 24: - offset += (offset << 1); - pReg->sisRegs3C4[BankReg] |= 0x10; - pReg->sisRegs3C4[MMIOEnable] |= 0x90; - break; - } - - pReg->sisRegs3C4[LinearAdd0] = (pSiS->FbAddress & 0x07F80000) >> 19; - pReg->sisRegs3C4[LinearAdd1] = ((pSiS->FbAddress & 0xF8000000) >> 27) | 0x60; - pReg->sisRegs3x4[Offset] = offset & 0xFF; - pReg->sisRegs3C4[CRTCOff] = ((offset & 0xF00) >> 4) | - (((mode->CrtcVTotal-2) & 0x400) >> 10 ) | - (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) | - ((mode->CrtcVSyncStart & 0x400) >> 8 ) | - (((mode->CrtcVSyncStart) & 0x400) >> 7 ) ; - - { - - SiSCalcClock(pScrn, clock, 2, vclk); - - pReg->sisRegs3C4[XR2A] = (vclk[Midx] - 1) & 0x7f ; - pReg->sisRegs3C4[XR2A] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; - pReg->sisRegs3C4[XR2B] = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */ - - if (vclk[Pidx] <= 4){ - pReg->sisRegs3C4[XR2B] |= (vclk[Pidx] -1 ) << 5 ; /* postscale 1,2,3,4 */ - pReg->sisRegs3C4[ClockBase] &= 0xBF; - } else { - pReg->sisRegs3C4[XR2B] |= ((vclk[Pidx] / 2) -1 ) << 5 ; /* postscale 6,8 */ - pReg->sisRegs3C4[ClockBase] |= 0x40; - } - pReg->sisRegs3C4[XR2B] |= 0x80 ; /* gain for high frequency */ - - if (clock > 135000) pReg->sisRegs3C4[ClockReg] |= 0x02; - - pReg->sisRegs3C2[0x00] = inb(0x3CC) | 0x0C; /* Programmable Clock */ - } - - if (pSiS->FastVram) - pReg->sisRegs3C4[ExtMiscCont5]|= 0xC0; - else - pReg->sisRegs3C4[ExtMiscCont5]&= ~0xC0; - - pReg->sisRegs3C4[GraphEng] |= 0x40; - pSiS->ValidWidth = TRUE; - pReg->sisRegs3C4[GraphEng] &= 0xCF; /* Clear logical width bits */ - - if (pScrn->bitsPerPixel == 24) { - pReg->sisRegs3C4[GraphEng] |= 0x30; /* Invalid logical width */ - pSiS->ValidWidth = FALSE; - } - else - { - switch ( pScrn->virtualX * (pScrn->bitsPerPixel >> 3) ) { - case 1024: - pReg->sisRegs3C4[GraphEng] |= 0x00; /* | 00 = No change */ - break; - case 2048: - pReg->sisRegs3C4[GraphEng] |= 0x10; - break; - case 4096: - pReg->sisRegs3C4[GraphEng] |= 0x20; - break; - default: - pReg->sisRegs3C4[GraphEng] = 0x30; /* Invalid logical width */ - pSiS->ValidWidth = FALSE; - break; - } - } + int i,max; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3, - "virtualX = %d depth = %d Logical width = %d\n", - pScrn->virtualX, pScrn->depth, pScrn->virtualX * (pScrn->bitsPerPixel >> 3)); + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n")); - if (!pSiS->NoAccel) { - pReg->sisRegs3C4[GraphEng] |= 0x40; - if (pSiS->TurboQueue) { - pReg->sisRegs3C4[GraphEng] |= 0x80; - pReg->sisRegs3C4[ExtMiscCont9] &= 0xFC; /* All Queue for 2D */ - if (pSiS->HWCursor) - pReg->sisRegs3C4[TurboQueueBase] = (pScrn->videoRam/32) - 2; - else - pReg->sisRegs3C4[TurboQueueBase] = (pScrn->videoRam/32) - 1; - } - pReg->sisRegs3C4[MMIOEnable] |= 0x60; /* At PCI base */ - } - pReg->sisRegs3C4[Mode64] |= 0x80; +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif - /* Set memclock */ - if ((pSiS->Chipset == PCI_CHIP_SIS5597) || (pSiS->Chipset == PCI_CHIP_SIS6326)) { - if (pSiS->MemClock > 66000) { - SiSCalcClock(pScrn, pSiS->MemClock, 1, vclk); - - pReg->sisRegs3C4[MemClock0] = (vclk[Midx] - 1) & 0x7f ; - pReg->sisRegs3C4[MemClock0] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; - pReg->sisRegs3C4[MemClock1] = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */ - if (vclk[Pidx] <= 4){ - pReg->sisRegs3C4[MemClock1] |= (vclk[Pidx] -1 ) << 5 ; /* postscale 1,2,3,4 */ - pReg->sisRegs3C4[ClockBase] &= 0x7F; - } else { - pReg->sisRegs3C4[MemClock1] |= ((vclk[Pidx] / 2) -1 ) << 5 ; /* postscale 6,8 */ - pReg->sisRegs3C4[ClockBase] |= 0x80; - } - -#if 1 /* Check programmed memory clock. Enable only to check the above code */ - mclk=14318*((pReg->sisRegs3C4[MemClock0] & 0x7f)+1); - mclk=mclk/((pReg->sisRegs3C4[MemClock1] & 0x0f)+1); - Base = pReg->sisRegs3C4[ClockBase]; - if ( (Base & 0x80)==0 ) { - mclk = mclk / (((pReg->sisRegs3C4[MemClock1] & 0x60) >> 5)+1); - } else { - if ((pReg->sisRegs3C4[MemClock1] & 0x60) == 0x40) { mclk=mclk/6;} - if ((pReg->sisRegs3C4[MemClock1] & 0x60) == 0x60) { mclk=mclk/8;} - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,2, - "Setting memory clock to %.3f MHz\n", - mclk/1000.0); + switch(pSiS->Chipset) { + case PCI_CHIP_SIS5597: + max=0x3C; + break; + case PCI_CHIP_SIS6326: + case PCI_CHIP_SIS530: + max=0x3F; + break; + default: + max=0x37; + break; + } + + /* Save extended SR registers */ + for(i = 0x00; i <= max; i++) { + inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]); #endif - } } - MemBand = sisMemBandWidth(pScrn) / 10 ; - safetymargin = 1; - gap = 4; - - CRT_ENGthreshold = 0x0F ; - CRT_CPUthresholdLow = ((pScrn->depth*clock) / MemBand)+safetymargin; - CRT_CPUthresholdHigh = ((pScrn->depth*clock) / MemBand)+gap+safetymargin; - - if ( CRT_CPUthresholdLow > (pScrn->depth < 24 ? 0xe:0x0d) ) { - CRT_CPUthresholdLow = (pScrn->depth < 24 ? 0xe:0x0d); +#ifdef TWDEBUG + for(i = 0x00; i <= 0x3f; i++) { + inSISIDXREG(SISCR, i, max); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CR%02X - %02X \n", i,max); } +#endif - if ( CRT_CPUthresholdHigh > (pScrn->depth < 24 ? 0x10:0x0f) ) { - CRT_CPUthresholdHigh = (pScrn->depth < 24 ? 0x10:0x0f); - } + /* Save lock (will not be restored in SiSRestore()!) */ + inSISIDXREG(SISCR, 0x80, sisReg->sisRegs3D4[0x80]); - pReg->sisRegs3C4[CPUThreshold] = (CRT_ENGthreshold & 0x0F) | - (CRT_CPUthresholdLow & 0x0F)<<4 ; - pReg->sisRegs3C4[CRTThreshold] = CRT_CPUthresholdHigh & 0x0F; + sisReg->sisRegs3C2 = inSISREG(SISMISCR); /* Misc */ - outw(VGA_SEQ_INDEX, (temp << 8) | 0x05); /* Relock Registers */ - return(TRUE); + /* TW: Save TV registers */ + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + outSISIDXREG(SISCR, 0x80, 0x86); + for(i = 0x00; i <= 0x44; i++) { + sisReg->sis6326tv[i] = SiS6326GetTVReg(pScrn, i); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VR%02X - %02X \n", i,sisReg->sis6326tv[i]); +#endif + } + } } -void +static void SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); - int vgaIOBase; int i,max; - unsigned char temp; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); - vgaHWGetIOBase(VGAHWPTR(pScrn)); - vgaIOBase = VGAHWPTR(pScrn)->IOBase; + unsigned char tmp; - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); - - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - max=0x39; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->Chipset) { + case PCI_CHIP_SIS5597: + max = 0x3C; break; - case PCI_CHIP_SIS6326: - max=0x3c; + case PCI_CHIP_SIS6326: + case PCI_CHIP_SIS530: + max = 0x3F; break; - default: - max=0x37; + default: + max = 0x37; break; } + /* Disable TV on 6326 before restoring */ + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + outSISIDXREG(SISCR, 0x80, 0x86); + tmp = SiS6326GetTVReg(pScrn, 0x00); + tmp &= ~0x04; + SiS6326SetTVReg(pScrn, 0x00, tmp); + } + + /* Restore other extended SR registers */ for (i = 0x06; i <= max; i++) { - outb(VGA_SEQ_INDEX,i); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,4, - "XR%X Contents - %02X ", i, inb(VGA_SEQ_DATA)); - outb(VGA_SEQ_DATA,sisReg->sisRegs3C4[i]); - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,4, - "Restore to - %02X Read after - %02X\n",sisReg->sisRegs3C4[i], inb(VGA_SEQ_DATA)); + if((i == 0x13) || (i == 0x2a) || (i == 0x2b)) continue; + outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); } - outw(vgaIOBase + 4, (sisReg->sisRegs3x4[Offset] << 8) | Offset); - outb(0x3C2, sisReg->sisRegs3C2[0x00]); + /* Now restore VCLK (with correct SR38 setting) */ + outSISIDXREG(SISSR, 0x13, sisReg->sisRegs3C4[0x13]); + outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]); + outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]); + + /* Misc */ + outSISREG(SISMISCW, sisReg->sisRegs3C2); /* MemClock needs this to take effect */ - - outw(VGA_SEQ_INDEX, 0x0100); /* Synchronous Reset */ - outw(VGA_SEQ_INDEX, 0x0300); /* End Reset */ + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + + /* TW: Restore TV registers */ + pSiS->SiS6326Flags &= ~SIS6326_TVON; + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + for(i = 0x01; i <= 0x44; i++) { + SiS6326SetTVReg(pScrn, i, sisReg->sis6326tv[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VR%02x restored to %02x\n", + i, sisReg->sis6326tv[i]); +#endif + } + tmp = SiS6326GetXXReg(pScrn, 0x13); + SiS6326SetXXReg(pScrn, 0x13, 0xfa); + tmp = SiS6326GetXXReg(pScrn, 0x14); + SiS6326SetXXReg(pScrn, 0x14, 0xc8); + if(!(sisReg->sisRegs3C4[0x0D] & 0x04)) { + tmp = SiS6326GetXXReg(pScrn, 0x13); + SiS6326SetXXReg(pScrn, 0x13, 0xf6); + tmp = SiS6326GetXXReg(pScrn, 0x14); + SiS6326SetXXReg(pScrn, 0x14, 0xbf); + } + if(sisReg->sis6326tv[0] & 0x04) pSiS->SiS6326Flags |= SIS6326_TVON; + } +} + +/* Save SiS 300 series register contents */ +static void +SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) +{ + SISPtr pSiS = SISPTR(pScrn); + int i; + + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n")); + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + /* Save SR registers */ + for(i = 0x00; i <= 0x3D; i++) { + inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]); +#endif + } + + /* Save CR registers */ + for(i = 0x00; i < 0x40; i++) { + inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CR%02X Contents - %02X \n", i,sisReg->sisRegs3D4[i]); +#endif + } + + /* Save Misc register */ + sisReg->sisRegs3C2 = inSISREG(SISMISCR); + + /* Save FQBQ and GUI timer settings */ + if(pSiS->Chipset == PCI_CHIP_SIS630) { + sisReg->sisRegsPCI50 = pciReadLong(0x00000000, 0x50); + sisReg->sisRegsPCIA0 = pciReadLong(0x00000000, 0xA0); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI Config 50 = %lx\n", sisReg->sisRegsPCI50); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI Config A0 = %lx\n", sisReg->sisRegsPCIA0); +#endif + } + + /* Save panel link/video bridge registers */ +#ifndef TWDEBUG + if(!pSiS->UseVESA) { +#endif + if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg); + if (pSiS->VBFlags & VB_301) + (*pSiS->SiSSave2)(pScrn, sisReg); + if (pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) + (*pSiS->SiSSave3)(pScrn, sisReg); +#ifndef TWDEBUG + } +#endif - outw(VGA_SEQ_INDEX, (temp << 8) | 0x05); /* Relock Registers */ + /* Save Mode number */ +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) + if(!(pSiS->UseVESA)) +#endif + pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave); +#endif } -void -SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) + +/* Restore SiS300 series register contents */ +static void +SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); - int vgaIOBase; - int i,max; - unsigned char temp; + int i,temp; + CARD32 temp1; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); - vgaHWGetIOBase(VGAHWPTR(pScrn)); - vgaIOBase = VGAHWPTR(pScrn)->IOBase; +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"vgaIOBase = %04X\n", vgaIOBase); + /* TW: Wait for accelerator to finish on-going drawing operations. */ + inSISIDXREG(SISSR, 0x1E, temp); + if(temp & (0x40|0x10|0x02)) { + while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; + while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; + while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; + } + + if(!(pSiS->UseVESA)) { + if(pSiS->VBFlags & VB_LVDS) { + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + } + } - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); + /* Restore extended CR registers */ + for(i = 0x19; i < 0x40; i++) { + outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); + } - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - max=0x39; - break; - case PCI_CHIP_SIS6326: - max=0x3c; - break; - default: - max=0x37; - break; - } + if(pSiS->Chipset != PCI_CHIP_SIS300) { + unsigned char val; + inSISIDXREG(SISCR, 0x1A, val); + if(val == sisReg->sisRegs3D4[0x19]) + outSISIDXREG(SISCR, 0x1A, sisReg->sisRegs3D4[0x19]); + inSISIDXREG(SISCR,0x19,val); + if(val == sisReg->sisRegs3D4[0x1A]) + outSISIDXREG(SISCR, 0x19, sisReg->sisRegs3D4[0x1A]); + } - for (i = 0x06; i <= max; i++) { - outb(VGA_SEQ_INDEX, i); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,4, - "XR%02X Contents - %02X \n", i, inb(VGA_SEQ_DATA)); - sisReg->sisRegs3C4[i] = inb(VGA_SEQ_DATA); + /* Set (and leave) PCI_IO_ENABLE on if accelerators are on */ + if(sisReg->sisRegs3C4[0x1e] & 0x50) { + sisReg->sisRegs3C4[0x20] |= 0x20; + outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); + } + + /* TW: If TQ is switched on, don't switch it off ever again! + * Therefore, always restore registers with TQ enabled. + */ + if((!pSiS->NoAccel) && (pSiS->TurboQueue)) { + temp = (pScrn->videoRam/64) - 8; + sisReg->sisRegs3C4[0x26] = temp & 0xFF; + sisReg->sisRegs3C4[0x27] = ((temp >> 8) & 3) | 0xF0; + } + + /* Restore extended SR registers */ + for (i = 0x06; i <= 0x3D; i++) { + temp = sisReg->sisRegs3C4[i]; + if(!(pSiS->UseVESA)) { + if(pSiS->VBFlags & VB_LVDS) { + if(i == 0x11) { + inSISIDXREG(SISSR,0x11,temp); + temp &= 0x0c; + temp |= (sisReg->sisRegs3C4[i] & 0xf3); + } + } + } + outSISIDXREG(SISSR, i, temp); + } + + /* TW: Restore VCLK and ECLK */ + if(pSiS->VBFlags & (VB_LVDS | VB_301B)) { + outSISIDXREG(SISSR,0x31,0x20); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x80); + outSISIDXREG(SISSR,0x31,0x10); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x80); + } + outSISIDXREG(SISSR,0x31,0x00); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x80); + if(pSiS->VBFlags & (VB_LVDS | VB_301B)) { + outSISIDXREG(SISSR,0x31,0x20); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + outSISIDXREG(SISSR,0x31,0x10); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + outSISIDXREG(SISSR,0x31,0x00); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + } + + /* Restore Misc register */ + outSISREG(SISMISCW, sisReg->sisRegs3C2); + + /* Restore FQBQ and GUI timer settings */ + if(pSiS->Chipset == PCI_CHIP_SIS630) { + temp1 = pciReadLong(0x00000000, 0x50); + if(pciReadLong(0x00000000, 0x00) == 0x06301039) { + temp1 &= 0xf0ffffff; + temp1 |= (sisReg->sisRegsPCI50 & ~0xf0ffffff); + } else { /* 730 */ + temp1 &= 0xfffff9ff; + temp1 |= (sisReg->sisRegsPCI50 & ~0xfffff9ff); + } + pciWriteLong(0x00000000, 0x50, temp1); + + temp1 = pciReadLong(0x00000000, 0xA0); + if(pciReadLong(0x00000000, 0x00) == 0x06301039) { + temp1 &= 0xf0ffffff; + temp1 |= (sisReg->sisRegsPCIA0 & ~0xf0ffffff); + } else { /* 730 */ + temp1 &= 0x00ffffff; + temp1 |= (sisReg->sisRegsPCIA0 & ~0x00ffffff); + } + pciWriteLong(0x00000000, 0xA0, temp1); + } + /* Restore panel link/video bridge registers */ + if(!(pSiS->UseVESA)) { + if(pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg); + if(pSiS->VBFlags & VB_301) + (*pSiS->SiSRestore2)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) + (*pSiS->SiSRestore3)(pScrn, sisReg); } - outb(vgaIOBase + 4, Offset); - sisReg->sisRegs3x4[Offset] = inb(VGA_SEQ_DATA); - sisReg->sisRegs3C2[0x00] = inb(0x3CC); + /* MemClock needs this to take effect */ + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ - outw(VGA_SEQ_INDEX, (temp << 8) | 0x05); /* Relock Registers */ + /* Restore mode number */ +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) + if(!(pSiS->UseVESA)) +#endif + SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); } -static void -SiSShowCursor(ScrnInfoPtr pScrn) +/* Save SiS315 series register contents */ +static void +SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) { - unsigned char temp, temp2; + SISPtr pSiS = SISPTR(pScrn); + int i; + + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n")); + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + /* Save SR registers */ + for (i = 0x00; i <= 0x3F; i++) { + inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]); +#endif + } + + /* TW: Save command queue location */ + sisReg->sisMMIO85C0 = MMIO_IN32(pSiS->IOBase, 0x85C0); + + /* Save CR registers */ + for (i = 0x00; i <= 0x7a; i++) { + inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CR%02X Contents - %02X \n", i,sisReg->sisRegs3D4[i]); +#endif + } + + /* Save video capture registers */ + for (i = 0x00; i <= 0x4f; i++) { + inSISIDXREG(SISCAP, i, sisReg->sisCapt[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Capt%02X Contents - %02X \n", i,sisReg->sisCapt[i]); +#endif + } + + /* Save video playback registers */ + for (i = 0x00; i <= 0x3f; i++) { + inSISIDXREG(SISVID, i, sisReg->sisVid[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Vid%02X Contents - %02X \n", i,sisReg->sisVid[i]); +#endif + } - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp2 = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); + /* Save Misc register */ + sisReg->sisRegs3C2 = inSISREG(SISMISCR); - outb(VGA_SEQ_INDEX, 0x06); temp = inb(VGA_SEQ_DATA); - outb(VGA_SEQ_DATA, temp | 0x40); + /* Save panel link/video bridge registers */ +#ifndef TWDEBUG + if (!pSiS->UseVESA) { +#endif + if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg); + if (pSiS->VBFlags & VB_301) + (*pSiS->SiSSave2)(pScrn, sisReg); + if (pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) + (*pSiS->SiSSave3)(pScrn, sisReg); +#ifndef TWDEBUG + } +#endif - outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05); + /* Save mode number */ +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) + if(!(pSiS->UseVESA)) +#endif + pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave); +#endif } -static void -SiSHideCursor(ScrnInfoPtr pScrn) { - unsigned char temp, temp2; +/* Restore SiS315/330 series register contents */ +static void +SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) +{ + SISPtr pSiS = SISPTR(pScrn); + int i,temp; - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp2 = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); - outb(VGA_SEQ_INDEX, 0x06); temp = inb(VGA_SEQ_DATA); - outb(VGA_SEQ_DATA, temp & 0xBF); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + /* Wait for accelerator to finish on-going drawing operations. */ + inSISIDXREG(SISSR, 0x1E, temp); + if (temp & (0x40|0x10|0x02)) { /* 0x40 = 2D, 0x10 = 3D enabled*/ + while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; + while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; + while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; + } - outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05); + /* Restore extended CR registers */ + for (i = 0x19; i < 0x5C; i++) { + outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); + } + outSISIDXREG(SISCR, 0x79, sisReg->sisRegs3D4[0x79]); + outSISIDXREG(SISCR, 0x63, sisReg->sisRegs3D4[0x63]); + + /* Leave PCI_IO_ENABLE on if accelerators are on (Is this required?) */ + if (sisReg->sisRegs3C4[0x1e] & 0x50) { /*0x40=2D, 0x10=3D*/ + sisReg->sisRegs3C4[0x20] |= 0x20; + outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); + } + + /* We reset the command queue before restoring. + * This might be required because we never know what + * console driver (like the kernel framebuffer driver) + * or application is running and which queue mode it + * uses. + */ + outSISIDXREG(SISSR, 0x27, 0x1F); + outSISIDXREG(SISSR, 0x26, 0x01); + + /* Restore extended SR registers */ + for (i = 0x06; i <= 0x3F; i++) { + outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); + } + /* Restore VCLK and ECLK */ + andSISIDXREG(SISSR,0x31,0xcf); + if(pSiS->VBFlags & VB_LVDS) { + orSISIDXREG(SISSR,0x31,0x20); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x80); + andSISIDXREG(SISSR,0x31,0xcf); + orSISIDXREG(SISSR,0x31,0x10); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x80); + andSISIDXREG(SISSR,0x31,0xcf); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x01); + outSISIDXREG(SISSR,0x31,0x20); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + outSISIDXREG(SISSR,0x31,0x10); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + outSISIDXREG(SISSR,0x31,0x00); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + } else { + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x01); + } + + /* Initialize read/write pointer for command queue */ + MMIO_OUT32(pSiS->IOBase, 0x85C4, MMIO_IN32(pSiS->IOBase, 0x85C8)); + /* Restore queue location */ + MMIO_OUT32(pSiS->IOBase, 0x85C0, sisReg->sisMMIO85C0); + + /* Restore Misc register */ + outSISREG(SISMISCW, sisReg->sisRegs3C2); + + /* Restore panel link/video bridge registers */ + if(!(pSiS->UseVESA)) { + if(pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg); + if(pSiS->VBFlags & VB_301) + (*pSiS->SiSRestore2)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) + (*pSiS->SiSRestore3)(pScrn, sisReg); + } + + /* MemClock needs this to take effect */ + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + + /* Restore Mode number */ +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) + if(!(pSiS->UseVESA)) +#endif + SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); } -static void -SiSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +/* Save SiS301 bridge register contents */ +static void +SiS301Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) { - unsigned char temp2; - - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp2 = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); - - if (x < 0) { - outw(VGA_SEQ_INDEX, (-x)<<8 | 0x1C); - x = 0; - } else - outw(VGA_SEQ_INDEX, 0x001C); - - if (y < 0) { - outw(VGA_SEQ_INDEX, (-y)<<8 | 0x1F); - y = 0; - } else - outw(VGA_SEQ_INDEX, 0x001F); - - outw(VGA_SEQ_INDEX, (x&0xFF)<<8 | 0x1A); - outw(VGA_SEQ_INDEX, (x&0xFF00) | 0x1B); - outw(VGA_SEQ_INDEX, (y&0xFF)<<8 | 0x1D); - outw(VGA_SEQ_INDEX, (y&0xFF00) | 0x1E); - - outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05); + SISPtr pSiS = SISPTR(pScrn); + int i; + int Part1max=0, Part2max=0, Part3max=0, Part4max=0; + + /* Highest register number to save/restore */ + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + Part1max = 0x1d; + Part2max = 0x45; + Part3max = 0x3e; + Part4max = 0x1b; + break; + case SIS_315_VGA: + Part1max = 0x2e; /* 0x23, but we also need 2d-2e */ + Part2max = 0x45; + Part3max = 0x3e; + Part4max = 0x1b; + break; + } + + for (i=0; i<=Part1max; i++) { + inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301Save: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]); +#endif + } + for (i=0; i<=Part2max; i++) { + inSISIDXREG(SISPART2, i, sisReg->VBPart2[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301Save: Part2Port 0x%02x = 0x%02x\n", i, sisReg->VBPart2[i]); +#endif + } + for (i=0; i<=Part3max; i++) { + inSISIDXREG(SISPART3, i, sisReg->VBPart3[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301Save: Part3Port 0x%02x = 0x%02x\n", i, sisReg->VBPart3[i]); +#endif + } + for (i=0; i<=Part4max; i++) { + inSISIDXREG(SISPART4, i, sisReg->VBPart4[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301Save: Part4Port 0x%02x = 0x%02x\n", i, sisReg->VBPart4[i]); +#endif + } + + sisReg->VBPart2[0] &= ~0x20; /* Disable VB Processor */ + sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */ } +/* Restore SiS301 bridge register contents */ static void -SiSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) { - unsigned char temp2; + SISPtr pSiS = SISPTR(pScrn); + int Part1max=0, Part2max=0, Part3max=0, Part4max=0; + + /* Highest register number to save/restore */ + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + Part1max = 0x1d; + Part2max = 0x45; + Part3max = 0x3e; + Part4max = 0x1b; + break; + case SIS_315_VGA: + Part1max = 0x23; + Part2max = 0x45; + Part3max = 0x3e; + Part4max = 0x1b; + break; + } - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp2 = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - outw(VGA_SEQ_INDEX, (fg & 0x000000FF)<<8 | 0x17); - outw(VGA_SEQ_INDEX, (fg & 0x0000FF00) | 0x18); - outw(VGA_SEQ_INDEX, (fg & 0x00FF0000)>>8 | 0x19); - outw(VGA_SEQ_INDEX, (bg & 0x000000FF)<<8 | 0x14); - outw(VGA_SEQ_INDEX, (bg & 0x0000FF00) | 0x15); - outw(VGA_SEQ_INDEX, (bg & 0x00FF0000)>>8 | 0x16); + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05); + /* Pre-restore Part1 */ + outSISIDXREG(SISPART1, 0x04, 0x00); + outSISIDXREG(SISPART1, 0x05, 0x00); + outSISIDXREG(SISPART1, 0x06, 0x00); + outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0]); + outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[1]); + + /* Pre-restore Part4 */ + outSISIDXREG(SISPART4, 0x0D, sisReg->VBPart4[0x0D]); + outSISIDXREG(SISPART4, 0x0C, sisReg->VBPart4[0x0C]); + + if (!(sisReg->sisRegs3D4[0x30] & 0x03) && + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + return; + } + + /* Restore Part1 */ + SetBlock(SISPART1, 0x02, Part1max, &(sisReg->VBPart1[0x02])); + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + /* Nothing special here. */ + break; + case SIS_315_VGA: + /* Restore extra registers on 315 series */ + SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C])); + break; + } + + /* Restore Part2 */ + SetBlock(SISPART2, 0x00, Part2max, &(sisReg->VBPart2[0x00])); + + /* Restore Part3 */ + SetBlock(SISPART3, 0x00, Part3max, &(sisReg->VBPart3[0x00])); + + /* Restore Part4 */ + SetBlock(SISPART4, 0x0E, 0x11, &(sisReg->VBPart4[0x0E])); + SetBlock(SISPART4, 0x13, Part4max, &(sisReg->VBPart4[0x13])); + + /* Post-restore Part4 (CRT2VCLK) */ + outSISIDXREG(SISPART4, 0x0A, 0x01); + outSISIDXREG(SISPART4, 0x0B, sisReg->VBPart4[0x0B]); + outSISIDXREG(SISPART4, 0x0A, sisReg->VBPart4[0x0A]); + outSISIDXREG(SISPART4, 0x12, 0x00); + outSISIDXREG(SISPART4, 0x12, sisReg->VBPart4[0x12]); + + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_DisplayOn(pSiS->SiS_Pr); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); } +/* Save SiS301B/302B/30xLV bridge register contents */ static void -SiSLoadCursorImage( - ScrnInfoPtr pScrn, - unsigned char *src -) +SiS301BSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) { - SISPtr pSiS = SISPTR(pScrn); - int cursoraddress = ((pScrn->videoRam * 1024) - 16384) / 262144; - unsigned char temp, temp2; + SISPtr pSiS = SISPTR(pScrn); + int i; + int Part1max=0, Part2max=0, Part3max=0, Part4max=0; + + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + Part1max = 0x37; /* 0x1d, but we also need 2c-2e, 35-37 */ + Part2max = 0x4d; + Part3max = 0x3e; + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) + Part4max = 0x34; + else + Part4max = 0x23; + break; + case SIS_315_VGA: + Part1max = 0x37; /* 0x23, but we also need 2c-2e, 35-37 */ + Part2max = 0x4d; + Part3max = 0x3e; + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) + Part4max = 0x34; + else + Part4max = 0x23; + break; + } + + for (i=0; i<=Part1max; i++) { + inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301BSave: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]); +#endif + } + for (i=0; i<=Part2max; i++) { + inSISIDXREG(SISPART2, i, sisReg->VBPart2[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301BSave: Part2Port 0x%02x = 0x%02x\n", i, sisReg->VBPart2[i]); +#endif + } + for (i=0; i<=Part3max; i++) { + inSISIDXREG(SISPART3, i, sisReg->VBPart3[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301BSave: Part3Port 0x%02x = 0x%02x\n", i, sisReg->VBPart3[i]); +#endif + } + for (i=0; i<=Part4max; i++) { + inSISIDXREG(SISPART4, i, sisReg->VBPart4[i]); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "301BSave: Part4Port 0x%02x = 0x%02x\n", i, sisReg->VBPart4[i]); +#endif + } + sisReg->VBPart2[0] &= ~0x20; /* Disable VB Processor */ + sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */ +} + +/* Restore SiS301B/302B/301LV/302LV bridge register contents */ +static void +SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) +{ + SISPtr pSiS = SISPTR(pScrn); + int Part1max=0, Part2max=0, Part3max=0, Part4max=0; + + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + Part1max = 0x23; + Part2max = 0x4d; + Part3max = 0x3e; + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) + Part4max = 0x24; + else + Part4max = 0x22; + break; + case SIS_315_VGA: + Part1max = 0x23; + Part2max = 0x4d; + Part3max = 0x3e; + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) + Part4max = 0x24; + else + Part4max = 0x22; + break; + } + + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + + /* Pre-restore Part1 */ + outSISIDXREG(SISPART1, 0x04, 0x00); + outSISIDXREG(SISPART1, 0x05, 0x00); + outSISIDXREG(SISPART1, 0x06, 0x00); + outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0x00]); + outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[0x01]); + /* Mode reg 0x01 became 0x2e on 315 series (0x01 still contains FIFO) */ + if(pSiS->VGAEngine == SIS_315_VGA) + outSISIDXREG(SISPART1, 0x2e, sisReg->VBPart1[0x2e]); + + /* Pre-restore Part4 */ + outSISIDXREG(SISPART4, 0x0D, sisReg->VBPart4[0x0D]); + outSISIDXREG(SISPART4, 0x0C, sisReg->VBPart4[0x0C]); + + if (!(sisReg->sisRegs3D4[0x30] & 0x03) && + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + return; + } + + /* Restore Part1 */ + SetBlock(SISPART1, 0x02, Part1max, &(sisReg->VBPart1[0x02])); + if(pSiS->VGAEngine == SIS_315_VGA) { + SetBlock(SISPART1, 0x2C, 0x2D, &(sisReg->VBPart1[0x2C])); + SetBlock(SISPART1, 0x35, 0x37, &(sisReg->VBPart1[0x35])); + } + + /* Restore Part2 */ + SetBlock(SISPART2, 0x00, Part2max, &(sisReg->VBPart2[0x00])); - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp2 = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); + /* Restore Part3 */ + SetBlock(SISPART3, 0x00, Part3max, &(sisReg->VBPart3[0x00])); - memcpy((unsigned char *)pSiS->FbBase + (pScrn->videoRam * 1024) - 16384, - src, pSiS->CursorInfoRec->MaxWidth * - pSiS->CursorInfoRec->MaxHeight / 4); + /* Restore Part4 */ + SetBlock(SISPART4, 0x0E, 0x11, &(sisReg->VBPart4[0x0E])); + SetBlock(SISPART4, 0x13, Part4max, &(sisReg->VBPart4[0x13])); - outb(VGA_SEQ_INDEX, 0x38); temp = inb(VGA_SEQ_DATA); - outb(VGA_SEQ_DATA, (temp & 0x0F) | (cursoraddress << 4)); - outb(VGA_SEQ_INDEX, 0x1E); temp = inb(VGA_SEQ_DATA); outb(VGA_SEQ_DATA, (temp & 0xF7) | 0x08); + /* Post-restore Part4 (CRT2VCLK) */ + outSISIDXREG(SISPART4, 0x0A, sisReg->VBPart4[0x0A]); + outSISIDXREG(SISPART4, 0x0B, sisReg->VBPart4[0x0B]); + outSISIDXREG(SISPART4, 0x12, 0x00); + outSISIDXREG(SISPART4, 0x12, sisReg->VBPart4[0x12]); - outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05); + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_DisplayOn(pSiS->SiS_Pr); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); } -static Bool -SiSUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +/* Save LVDS bridge (+ Chrontel) register contents */ +static void +SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) { -#if 0 - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + int i; + + /* Save Part1 */ + for (i=0; i<0x46; i++) { + inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "LVDSSave: Part1Port 0x%02x = 0x%02x\n", + i, sisReg->VBPart1[i]); +#endif + } + + /* Save Chrontel registers */ + if (pSiS->VBFlags & VB_CHRONTEL) { + if (pSiS->ChrontelType == CHRONTEL_700x) { + for (i=0; i<0x1D; i++) { + sisReg->ch70xx[i] = SiS_GetCH700x(pSiS->SiS_Pr, ch700xidx[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "LVDSSave: Chrontel 0x%02x = 0x%02x\n", + ch700xidx[i], sisReg->ch70xx[i]); +#endif + } + } else { + for (i=0; i<35; i++) { + sisReg->ch70xx[i] = SiS_GetCH701x(pSiS->SiS_Pr, ch701xidx[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "LVDSSave: Chrontel 0x%02x = 0x%02x\n", + ch701xidx[i], sisReg->ch70xx[i]); #endif - return TRUE; + } + } + } + + sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */ } -Bool -SiSHWCursorInit(ScreenPtr pScreen) +/* Restore LVDS bridge (+ Chrontel) register contents */ +static void +SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSiS = SISPTR(pScrn); - xf86CursorInfoPtr infoPtr; -#if 0 - int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8; - - if (memory > (pScrn->videoRam * 1024 - 16384)) return FALSE; -#endif - infoPtr = xf86CreateCursorInfoRec(); - if(!infoPtr) return FALSE; - - pSiS->CursorInfoRec = infoPtr; - - infoPtr->MaxWidth = 64; - infoPtr->MaxHeight = 64; - infoPtr->Flags = - HARDWARE_CURSOR_INVERT_MASK | - HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | - HARDWARE_CURSOR_NIBBLE_SWAPPED | - HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; - infoPtr->SetCursorColors = SiSSetCursorColors; - infoPtr->SetCursorPosition = SiSSetCursorPosition; - infoPtr->LoadCursorImage = SiSLoadCursorImage; - infoPtr->HideCursor = SiSHideCursor; - infoPtr->ShowCursor = SiSShowCursor; - infoPtr->UseHWCursor = SiSUseHWCursor; - - return(xf86InitCursor(pScreen, infoPtr)); + SISPtr pSiS = SISPTR(pScrn); + int i; + USHORT wtemp; + + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + if(pSiS->sishw_ext.jChipType == SIS_730) { + outSISIDXREG(SISPART1, 0x00, 0x80); + } + + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + + if(pSiS->VBFlags & VB_CHRONTEL) { + /* Restore Chrontel registers */ + if(pSiS->ChrontelType == CHRONTEL_700x) { + for(i=0; i<0x11; i++) { + wtemp = ((sisReg->ch70xx[i]) << 8) | (ch700xidx[i] & 0x00FF); + SiS_SetCH700x(pSiS->SiS_Pr, wtemp); + } + } else { + for(i=0; i<34; i++) { + wtemp = ((sisReg->ch70xx[i]) << 8) | (ch701xidx[i] & 0x00FF); + SiS_SetCH701x(pSiS->SiS_Pr, wtemp); + } + } + } + + /* pre-restore Part1 */ + outSISIDXREG(SISPART1, 0x04, 0x00); + outSISIDXREG(SISPART1, 0x05, 0x00); + outSISIDXREG(SISPART1, 0x06, 0x00); + outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0]); + if(pSiS->VGAEngine == SIS_300_VGA) { + outSISIDXREG(SISPART1, 0x01, (sisReg->VBPart1[1] | 0x80)); + } else { + outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[1]); + } + + if (!(sisReg->sisRegs3D4[0x30] & 0x03) && + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + return; + } + + /* Restore Part1 */ + if(pSiS->VGAEngine == SIS_300_VGA) { + outSISIDXREG(SISPART1, 0x02, (sisReg->VBPart1[2] | 0x40)); + } else { + outSISIDXREG(SISPART1, 0x02, sisReg->VBPart1[2]); + } + SetBlock(SISPART1, 0x03, 0x23, &(sisReg->VBPart1[0x03])); + if(pSiS->VGAEngine == SIS_315_VGA) { + SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C])); + SetBlock(SISPART1, 0x35, 0x37, &(sisReg->VBPart1[0x35])); /* Panel Link Scaler */ + } + + /* For 550 DSTN registers */ + if (pSiS->DSTN || pSiS->FSTN) { + SetBlock(SISPART1, 0x25, 0x2E, &(sisReg->VBPart1[0x25])); + SetBlock(SISPART1, 0x30, 0x45, &(sisReg->VBPart1[0x30])); + } + + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_DisplayOn(pSiS->SiS_Pr); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); +} + +/* Restore output selection registers */ +void +SiSRestoreBridge(ScrnInfoPtr pScrn, SISRegPtr sisReg) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char temp = 0; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + outSISIDXREG(SISCR, 0x30, sisReg->sisRegs3D4[0x30]); + outSISIDXREG(SISCR, 0x31, sisReg->sisRegs3D4[0x31]); + outSISIDXREG(SISCR, 0x33, sisReg->sisRegs3D4[0x33]); + outSISIDXREG(SISCR, 0x34, sisReg->sisRegs3D4[0x34]); + outSISIDXREG(SISCR, 0x36, sisReg->sisRegs3D4[0x36]); + outSISIDXREG(SISCR, 0x37, sisReg->sisRegs3D4[0x37]); + if(pSiS->Chipset != PCI_CHIP_SIS300) { + switch(pSiS->VGAEngine) { + case SIS_300_VGA: temp = 0x35; break; + case SIS_315_VGA: temp = 0x38; break; + } + if(temp) { + outSISIDXREG(SISCR, temp, sisReg->sisRegs3D4[temp]); + } + } + if(pSiS->VGAEngine == SIS_315_VGA) { + outSISIDXREG(SISCR, 0x39, sisReg->sisRegs3D4[0x39]); + outSISIDXREG(SISCR, 0x63, sisReg->sisRegs3D4[0x63]); + outSISIDXREG(SISCR, 0x79, sisReg->sisRegs3D4[0x79]); + } } unsigned int SiSddc1Read(ScrnInfoPtr pScrn) { -#if 0 SISPtr pSiS = SISPTR(pScrn); -#endif - int vgaIOBase = VGAHWPTR(pScrn)->IOBase; - unsigned char temp, temp2; + unsigned char temp; - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - temp2 = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif /* Wait until vertical retrace is in progress. */ - while (inb(vgaIOBase + 0xA) & 0x08); - while (!(inb(vgaIOBase + 0xA) & 0x08)); + while(inSISREG(SISINPSTAT) & 0x08); + while(!(inSISREG(SISINPSTAT) & 0x08)); /* Get the result */ - outb(VGA_SEQ_INDEX, 0x11); temp = inb(VGA_SEQ_DATA); + inSISIDXREG(SISSR, 0x11, temp); - outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05); + return((temp & 0x02)>>1); +} - return ((temp & 0x02)>>1); +#if 0 /* TW: The following function should take a threshold value + * from predefined tables. This is only needed on some + * 530 boards, which have an ESS sound device on-board. + * However, I don't know how to calculate the index to + * be submitted to this function. + */ +unsigned short +SiS_CalcSpecial530Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode, int index) +{ + SISPtr pSiS = SISPTR(pScrn); + static const unsigned char t640x480[3][24] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,A9, /* b4 - 9d - depth 8 */ + 0, 0,11,14,14, 0, 0, 0, 0, 0, 0,9D }, + { 0, 0, 0, 0, 0,12,15, 0, 0, 0,92,91, /* 9c - 85 - depth 16 */ + 0,31,31,31,31, 0, 0, 0, 0, 0, 0,85 }, + { 0, 0, 0, 0, 0,17,22,25, 0, 0, 0,79, /* 84 - ? - depth 32 */ + 0,31,31, 0, 0, 0, 0, 0, 0, 0, 0,6d } + } + static const unsigned char t800x600[3][24] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,61, + 0,18,25,30,27,31,31,31, 0, 0, 0, 0 }, + {55, 0, 0, 0, 0, 9,10,15,18,19, 0, 0, + ... to be continued + + depthindex = (pSiS->CurrentLayout.bitsPerPixel + 1) >> 3; + if(depthindex == 3) return(0); + if(depthindex == 4) depthindex--; + depthindex--; + + switch(mode->HDisplay) { + case 640: + if(mode->VDisplay == 480) { + return(t640x480[depthindex][index]; + } else return(0); + case 800: + if(mode->VDisplay == 600) { + return(t800x600[depthindex][index]; + } else return(0); + case 1024: + if(mode->VDisplay == 768) { + return(t1024x768[depthindex][index]; + } else return(0); + case 1280: + if(mode->VDisplay == 1024) { + return(t1280x1024[depthindex][index]; + } else return(0); + case 1600: + if(mode->VDisplay == 1200) { + return(t1600x1200[depthindex][index]; + } else return(0); + default: return(0); + } } +#endif + +/* TW: Stub */ +static void +SiSThreshold(ScrnInfoPtr pScrn, DisplayModePtr mode, + unsigned short *Low, unsigned short *High) +{ + return; +} + /* Auxiliary function to find real memory clock (in Khz) */ +/* Not for 530/620 if UMA (on these, the mclk is stored in SR10) */ int -SiSMclk() -{ int mclk; - unsigned char Num, Denum, Base; +SiSMclk(SISPtr pSiS) +{ + int mclk; + unsigned char Num, Denum, Base; + + switch (pSiS->Chipset) { + + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS540: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: + /* Numerator */ + inSISIDXREG(SISSR, 0x28, Num); + mclk = 14318 * ((Num & 0x7f) + 1); + + /* Denumerator */ + inSISIDXREG(SISSR, 0x29, Denum); + mclk = mclk / ((Denum & 0x1f) + 1); + + /* Divider */ + if((Num & 0x80) != 0) mclk *= 2; + + /* Post-Scaler */ + if((Denum & 0x80) == 0) { + mclk = mclk / (((Denum & 0x60) >> 5) + 1); + } else { + mclk = mclk / ((((Denum & 0x60) >> 5) + 1) * 2); + } + break; + + case PCI_CHIP_SIS5597: + case PCI_CHIP_SIS6326: + case PCI_CHIP_SIS530: + default: + /* Numerator */ + inSISIDXREG(SISSR, 0x28, Num); + mclk = 14318 * ((Num & 0x7f) + 1); + + /* Denumerator */ + inSISIDXREG(SISSR, 0x29, Denum); + mclk = mclk / ((Denum & 0x1f) + 1); + + /* Divider. Doesn't work on older cards */ + if(pSiS->oldChipset >= OC_SIS5597) { + if(Num & 0x80) mclk *= 2; + } - /* Numerator */ + /* Post-scaler. Values' meaning depends on SR13 bit 7 */ + inSISIDXREG(SISSR, 0x13, Base); + if((Base & 0x80) == 0) { + mclk = mclk / (((Denum & 0x60) >> 5) + 1); + } else { + /* Values 00 and 01 are reserved */ + if ((Denum & 0x60) == 0x40) mclk /= 6; + if ((Denum & 0x60) == 0x60) mclk /= 8; + } + break; + } - read_xr(MemClock0,Num); - mclk=14318*((Num & 0x7f)+1); - - /* Denumerator */ - read_xr(MemClock1,Denum); - mclk=mclk/((Denum & 0x0f)+1); + return(mclk); +} - /* Divider. Don't seems to work for mclk with some cards ? */ - if ( (Num & 0x80)!=0 ) { - mclk = mclk*2; - } +/* This estimates the CRT2 clock we are going to use. + * The total bandwidth is to be reduced by the value + * returned here in order to get an idea of the maximum + * dotclock left for CRT1. + * Since we don't know yet, what mode the user chose, + * we return the maximum dotclock used by + * - either the LCD attached, or + * - TV + * For VGA2, we share the bandwith equally. + */ +static int +SiSEstimateCRT2Clock(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->VBLCDFlags & (VB_LCD_320x480 | VB_LCD_800x600 | VB_LCD_640x480)) + return 40000; + else if(pSiS->VBLCDFlags & (VB_LCD_1024x768 | VB_LCD_1024x600 | VB_LCD_1152x768)) + return 65000; + else if(pSiS->VBLCDFlags & VB_LCD_1280x768) + return 81000; + else if(pSiS->VBLCDFlags & (VB_LCD_1280x1024 | VB_LCD_1280x960 | VB_LCD_1400x1050)) + return 108000; + else if(pSiS->VBLCDFlags & VB_LCD_1600x1200) + return 162000; + else if((pSiS->VBLCDFlags & VB_LCD_CUSTOM) && (pSiS->SiS_Pr->CP_HaveCustomData)) + return pSiS->SiS_Pr->CP_MaxClock; + else + return 108000; + } else if(pSiS->VBFlags & CRT2_TV) { + if(pSiS->VBFlags & VB_CHRONTEL) { + switch(pSiS->VGAEngine) { + case SIS_300_VGA: + return 50000; + case SIS_315_VGA: + default: + return 70000; + } + } else if(pSiS->VBFlags & VB_SISBRIDGE) { + return 70000; + } + } + + return 0; +} + +/* Calculate the maximum dotclock */ +int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + int bus = pSiS->BusWidth; + int mclk = pSiS->MemClock; + int bpp = pSiS->CurrentLayout.bitsPerPixel; + int bytesperpixel = (bpp + 7) / 8; + float magic=0.0, total, crt2used, maxcrt2; + int crt2clock, max=0; + const float magic300[4] = { 1.2, 1.368421, 2.263158, 1.2}; + const float magic630[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; + const float magic315[4] = { 1.2, 1.368421, 1.368421, 1.2 }; + const float magic550[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; + BOOLEAN DHM, GetForCRT1; + + switch (pSiS->Chipset) { + + case PCI_CHIP_SIS5597: + total = ((mclk * (bus / 8)) * 0.7) / bytesperpixel; + if(total > 135000) total = 135000; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Maximum pixel clock at %d bpp is %g MHz\n", + bpp, total/1000); + return(int)(total); + + case PCI_CHIP_SIS6326: + total = ((mclk * (bus / 8)) * 0.7) / bytesperpixel; + if(total > 175500) total = 175500; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Maximum pixel clock at %d bpp is %g MHz\n", + bpp, total/1000); + return(int)(total); + + case PCI_CHIP_SIS530: + total = ((mclk * (bus / 8)) * 0.7) / bytesperpixel; + if(total > 230000) total = 230000; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Maximum pixel clock at %d bpp is %g MHz\n", + bpp, total/1000); + return(int)(total); + + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS540: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: + case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: + switch(pSiS->Chipset) { + case PCI_CHIP_SIS300: + magic = magic300[bus/64]; + max = 540000; + break; + case PCI_CHIP_SIS540: + case PCI_CHIP_SIS630: + magic = magic630[bus/64]; + max = 540000; + break; + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + magic = magic315[bus/64]; + max = 780000; + break; + case PCI_CHIP_SIS550: + magic = magic550[bus/64]; + max = 620000; + break; + case PCI_CHIP_SIS650: + magic = magic550[bus/64]; + max = 680000; + break; + case PCI_CHIP_SIS660: /* Guessed */ + magic = magic550[bus/64]; + max = 680000; + } + + PDEBUG(ErrorF("mclk: %d, bus: %d, magic: %g, bpp: %d\n", + mclk, bus, magic, bpp)); + + total = mclk * bus / bpp; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Memory bandwidth at %d bpp is %g MHz\n", bpp, total/1000); + + if((pSiS->VBFlags & CRT2_ENABLE) && (!pSiS->CRT1off)) { + + maxcrt2 = 135000; + if(pSiS->VBFlags & (VB_301B|VB_302B)) maxcrt2 = 162000; + if(pSiS->VBFlags & VB_30xBDH) maxcrt2 = 100000; + + crt2used = 0.0; + crt2clock = SiSEstimateCRT2Clock(pScrn); + if(crt2clock) { + crt2used = crt2clock + 2000; + } + DHM = FALSE; + GetForCRT1 = FALSE; + +#ifdef SISDUALHEAD + if((pSiS->DualHeadMode) && (pSiSEnt)) { + DHM = TRUE; + if(pSiS->SecondHead) GetForCRT1 = TRUE; + } +#endif +#ifdef SISMERGED + if(pSiS->MergedFB && IsForCRT2) { + DHM = TRUE; + GetForCRT1 = FALSE; + } +#endif + + if(DHM) { + + if(!GetForCRT1) { + + /* TW: First head = CRT2 */ + + if(crt2clock) { + /* TW: We use the mem bandwidth as max clock; this + * might exceed the 70% limit a bit, but that + * does not matter; we take care of that limit + * when we calc CRT1. Overall, we might use up + * to 85% of the memory bandwidth, which seems + * enough to use accel and video. + * The "* macic" is just to compensate the + * calculation below. + */ + total = crt2used * magic; + + } else { + /* We don't know about the second head's + * depth yet. So we assume it uses the + * same. But since the maximum dotclock + * is limited on CRT2, we can assume a + * maximum here. + */ + if((total / 2) > (maxcrt2 + 2000)) { + total = (maxcrt2 + 2000) * magic; + crt2used = maxcrt2 + 2000; + } else { + total /= 2; + crt2used = total; + } + + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth reserved for CRT2 is %g Mhz\n", + crt2used/1000); + + } else { + +#ifdef SISDUALHEAD + /* TW: Second head = CRT1 */ + + /* Now We know about the first head's depth, + * so we can calculate more accurately. + */ + + if(crt2clock) { + total -= (crt2used * pSiSEnt->pScrn_1->bitsPerPixel / bpp); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth reserved for CRT2 at %d bpp is %g Mhz\n", + bpp, + (crt2used * pSiSEnt->pScrn_1->bitsPerPixel / bpp)/1000); + } else { + total -= (pSiSEnt->maxUsedClock * pSiSEnt->pScrn_1->bitsPerPixel / bpp); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth reserved for CRT2 at %d bpp is %d Mhz\n", + bpp, + (pSiSEnt->maxUsedClock * pSiSEnt->pScrn_1->bitsPerPixel / bpp)/1000); + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth available for CRT1 is %g MHz\n", total/1000); +#endif + } + + } else { + + if(crt2clock) { + total -= crt2used; + } else { + if((total / 2) > (maxcrt2 + 2000)) { + total -= (maxcrt2 + 2000); + crt2used = maxcrt2 + 2000; + } else { + total /= 2; + crt2used = total; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth reserved for CRT2 is %g Mhz\n", crt2used/1000); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth available for CRT1 is %g MHz\n", total/1000); +#ifdef SISDUALHEAD + } +#endif + + } + total /= magic; + if(total > (max / 2)) total = max / 2; + return(int)(total); + + default: + return(135000); + } +} + +/* Load the palette. We do this for all supported color depths + * in order to support gamma correction. We hereby convert the + * given colormap to a complete 24bit color palette and enable + * the correspoding bit in SR7 to enable the 24bit lookup table. + * Gamma correction is only supported on CRT1. + * Why are there 6-bit-RGB values submitted even if bpp is 16 and + * weight is 565? (Maybe because rgbBits is 6?) + */ +void +SISLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, + VisualPtr pVisual) +{ + SISPtr pSiS = SISPTR(pScrn); + int i, j, index; + Bool dogamma1 = pSiS->CRT1gamma; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiS->DualHeadMode) dogamma1 = pSiSEnt->CRT1gamma; +#endif + + PDEBUG(ErrorF("SiSLoadPalette(%d)\n", numColors)); + +#ifdef SISDUALHEAD + if( ((pSiS->DualHeadMode) && (pSiS->SecondHead)) || + (!pSiS->DualHeadMode) ) { +#endif + + switch(pSiS->CurrentLayout.depth) { +#ifdef SISGAMMA + case 15: + if(dogamma1) { + orSISIDXREG(SISSR, 0x07, 0x04); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 32) { /* Paranoia */ + for(j=0; j<8; j++) { + outSISREG(SISCOLIDX, (index * 8) + j); + outSISREG(SISCOLDATA, colors[index].red << (8- pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].blue << (8 - pScrn->rgbBits)); + } + } + } + } else { + andSISIDXREG(SISSR, 0x07, ~0x04); + } + break; + case 16: + if(dogamma1) { + orSISIDXREG(SISSR, 0x07, 0x04); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 64) { /* Paranoia */ + for(j=0; j<4; j++) { + outSISREG(SISCOLIDX, (index * 4) + j); + outSISREG(SISCOLDATA, colors[index/2].red << (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index/2].blue << (8 - pScrn->rgbBits)); + } + } + } + } else { + andSISIDXREG(SISSR, 0x07, ~0x04); + } + break; + case 24: + if(dogamma1) { + orSISIDXREG(SISSR, 0x07, 0x04); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 256) { /* Paranoia */ + outSISREG(SISCOLIDX, index); + outSISREG(SISCOLDATA, colors[index].red); + outSISREG(SISCOLDATA, colors[index].green); + outSISREG(SISCOLDATA, colors[index].blue); + } + } + } else { + andSISIDXREG(SISSR, 0x07, ~0x04); + } + break; +#endif + default: + if((pScrn->rgbBits == 8) && (dogamma1)) + orSISIDXREG(SISSR, 0x07, 0x04); + else + andSISIDXREG(SISSR, 0x07, ~0x04); + for(i=0; i<numColors; i++) { + index = indices[i]; + outSISREG(SISCOLIDX, index); + outSISREG(SISCOLDATA, colors[index].red >> (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].green >> (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].blue >> (8 - pScrn->rgbBits)); + } + } + +#ifdef SISDUALHEAD + } + + if( ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) || + (!pSiS->DualHeadMode) ) { +#endif - /* Post-scaler. Values depends on SR13 bit 7 */ - outb(VGA_SEQ_INDEX, ClockBase); - Base = inb(VGA_SEQ_DATA); + switch(pSiS->VGAEngine) { + case SIS_300_VGA: + case SIS_315_VGA: + if(pSiS->VBFlags & CRT2_ENABLE) { + /* TW: Only the SiS bridges support a CRT2 palette */ + if(pSiS->VBFlags & VB_SISBRIDGE) { + (*pSiS->LoadCRT2Palette)(pScrn, numColors, indices, + colors, pVisual); + } + } + break; + } + +#ifdef SISDUALHEAD + } +#endif + +} + +static void +SiS301LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual) +{ + SISPtr pSiS = SISPTR(pScrn); + int i, j, index; + Bool dogamma2 = pSiS->CRT2gamma; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiS->DualHeadMode) dogamma2 = pSiSEnt->CRT2gamma; +#endif + + PDEBUG(ErrorF("SiS301LoadPalette(%d)\n", numColors)); + + /* 301B-DH does not support a color palette for LCD */ + if((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD)) return; + + switch(pSiS->CurrentLayout.depth) { +#ifdef SISGAMMA + case 15: + if(dogamma2) { + orSISIDXREG(SISPART4, 0x0d, 0x08); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 32) { /* Paranoia */ + for(j=0; j<8; j++) { + outSISREG(SISCOL2IDX, (index * 8) + j); + outSISREG(SISCOL2DATA, colors[index].red << (8- pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index].blue << (8 - pScrn->rgbBits)); + } + } + } + } else { + andSISIDXREG(SISPART4, 0x0d, ~0x08); + } + break; + case 16: + if(dogamma2) { + orSISIDXREG(SISPART4, 0x0d, 0x08); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 64) { /* Paranoia */ + for(j=0; j<4; j++) { + outSISREG(SISCOL2IDX, (index * 4) + j); + outSISREG(SISCOL2DATA, colors[index/2].red << (8 - pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index/2].blue << (8 - pScrn->rgbBits)); + } + } + } + } else { + andSISIDXREG(SISPART4, 0x0d, ~0x08); + } + break; + case 24: + if(dogamma2) { + orSISIDXREG(SISPART4, 0x0d, 0x08); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 256) { /* Paranoia */ + outSISREG(SISCOL2IDX, index); + outSISREG(SISCOL2DATA, colors[index].red); + outSISREG(SISCOL2DATA, colors[index].green); + outSISREG(SISCOL2DATA, colors[index].blue); + } + } + } else { + andSISIDXREG(SISPART4, 0x0d, ~0x08); + } + break; +#endif + default: + if((pScrn->rgbBits == 8) && (dogamma2)) + orSISIDXREG(SISPART4, 0x0d, 0x08); + else + andSISIDXREG(SISPART4, 0x0d, ~0x08); + for(i=0; i<numColors; i++) { + index = indices[i]; + outSISREG(SISCOL2IDX, index); + outSISREG(SISCOL2DATA, colors[index].red); + outSISREG(SISCOL2DATA, colors[index].green); + outSISREG(SISCOL2DATA, colors[index].blue); + } + } +} - if ( (Base & 0x80)==0 ) { - mclk = mclk / (((Denum & 0x60) >> 5)+1); +void +SISDACPreInit(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + switch (pSiS->Chipset) { + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: + pSiS->MaxClock = SiSMemBandWidth(pScrn, FALSE); + pSiS->SiSSave = SiS315Save; + pSiS->SiSSave2 = SiS301Save; + pSiS->SiSSave3 = SiS301BSave; + pSiS->SiSSaveLVDSChrontel = SiSLVDSChrontelSave; + pSiS->SiSRestore = SiS315Restore; + pSiS->SiSRestore2 = SiS301Restore; + pSiS->SiSRestore3 = SiS301BRestore; + pSiS->SiSRestoreLVDSChrontel = SiSLVDSChrontelRestore; + pSiS->LoadCRT2Palette = SiS301LoadPalette; + pSiS->SetThreshold = SiSThreshold; + pSiS->i2cInit = NULL; + break; + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS540: + pSiS->MaxClock = SiSMemBandWidth(pScrn, FALSE); + pSiS->SiSSave = SiS300Save; + pSiS->SiSSave2 = SiS301Save; + pSiS->SiSSave3 = SiS301BSave; + pSiS->SiSSaveLVDSChrontel = SiSLVDSChrontelSave; + pSiS->SiSRestore = SiS300Restore; + pSiS->SiSRestore2 = SiS301Restore; + pSiS->SiSRestore3 = SiS301BRestore; + pSiS->SiSRestoreLVDSChrontel = SiSLVDSChrontelRestore; + pSiS->LoadCRT2Palette = SiS301LoadPalette; + pSiS->SetThreshold = SiSThreshold; + pSiS->i2cInit = NULL; + break; + case PCI_CHIP_SIS5597: + case PCI_CHIP_SIS6326: + case PCI_CHIP_SIS530: + default: + pSiS->MaxClock = SiSMemBandWidth(pScrn, FALSE); + pSiS->SiSRestore = SiSRestore; + pSiS->SiSSave = SiSSave; + pSiS->SetThreshold = SiSThreshold; + pSiS->i2cInit = NULL; + break; } - else { - /* Values 00 and 01 are reserved */ - if ((Denum & 0x60) == 0x40) { mclk=mclk/6; - } - if ((Denum & 0x60) == 0x60) { mclk=mclk/8; - } +} + +static void +SetBlock(CARD16 port, CARD8 from, CARD8 to, CARD8 *DataPtr) +{ + CARD8 index; + + for(index = from; index <= to; index++, DataPtr++) { + outSISIDXREG(port, index, *DataPtr); } +} - return(mclk); +void +SiS6326SetTVReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data) +{ + SISPtr pSiS = SISPTR(pScrn); + outSISIDXREG(SISCR, 0xE0, index); + outSISIDXREG(SISCR, 0xE1, data); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "SiS6326: Setting Tv %02x to %02x\n", index, data); +#endif } -/* Returns estimated memory bandwidth in Kbits/sec (for dotclock defaults) */ -/* Currently, a very rough estimate (2 cycles / read ; 1 for fast_vram), with 70% to allow for */ -int -sisMemBandWidth(ScrnInfoPtr pScrn) +unsigned char +SiS6326GetTVReg(ScrnInfoPtr pScrn, CARD8 index) { - SISPtr pSiS = SISPTR(pScrn); - SISRegPtr pReg = &pSiS->ModeReg; - int band; - - if (pSiS->MemClock) - band=pSiS->MemClock; - else - band=SiSMclk(); - - if (((pReg->sisRegs3C4[Mode64] >> 1) & 3) == 0) /* Only 1 bank Vram */ - band = (band * 16); - else - band = (band * 32); - - if (pSiS->FastVram) { - band=band*2; - } else { - if (((pReg->sisRegs3C4[ExtMiscCont5]) & 0xC0) == 0xC0) band=band*2; - }; - - /* Check AGP 2x Transfer Rate */ - if (((pReg->sisRegs3C4[ExtConfStatus0]) & 0x30) == 0x30) band=band*2; + SISPtr pSiS = SISPTR(pScrn); + unsigned char data; - return(band*7/10); + outSISIDXREG(SISCR, 0xE0, index); + inSISIDXREG(SISCR, 0xE1, data); + return(data); } +void +SiS6326SetXXReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data) +{ + SISPtr pSiS = SISPTR(pScrn); + outSISIDXREG(SISCR, 0xE2, index); + outSISIDXREG(SISCR, 0xE3, data); +} + +unsigned char +SiS6326GetXXReg(ScrnInfoPtr pScrn, CARD8 index) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char data; + + outSISIDXREG(SISCR, 0xE2, index); + inSISIDXREG(SISCR, 0xE3, data); + return(data); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.h index 0faf237bd..8f4c2023c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.h @@ -1,5 +1,38 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.h,v 1.2 2001/04/19 14:11:37 alanh Exp $ */ -int compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div, +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.h,v 1.11 2003/06/10 16:44:19 twini Exp $ */ +/* + * DAC helper functions (Save/Restore, MemClk, etc) + * Definitions and prototypes + * + * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the provider not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The provider makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE PROVIDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE PROVIDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk> + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. + * Thomas Winischhofer <thomas@winischhofer.net> + */ + +int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div, int *out_sbit, int *out_scale); void SISDACPreInit(ScrnInfoPtr pScrn); unsigned int SiSddc1Read(ScrnInfoPtr pScrn); @@ -9,6 +42,46 @@ void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk); void SiSIODump(ScrnInfoPtr pScrn); -int SiSMemBandWidth(ScrnInfoPtr pScrn); -int SiSMclk(SISPtr pSiS); +int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2); +int SiSMclk(SISPtr pSiS); +void SiSRestoreBridge(ScrnInfoPtr pScrn, SISRegPtr sisReg); + +extern void SiS6326SetTVReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data); +extern unsigned char SiS6326GetTVReg(ScrnInfoPtr pScrn, CARD8 index); +extern void SiS6326SetXXReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data); +extern unsigned char SiS6326GetXXReg(ScrnInfoPtr pScrn, CARD8 index); + +extern int SiSCalcVRate(DisplayModePtr mode); + +/* TW: Functions from init.c & init301.c */ +extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +extern void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +extern void SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr); +extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx); +extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx); +extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx); +extern void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx); +extern USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx); +extern void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx); +extern void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh); +extern void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime); +extern USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine, + USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer); +extern void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo); +extern void SiS_DisplayOn(SiS_Private *SiS_Pr); +extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id); +extern void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable); +extern void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable); +#if 0 +extern void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr); +extern USHORT SiS_I2C_GetByte(SiS_Private *SiS_Pr); +extern Bool SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data); +extern Bool SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr); +extern void SiS_I2C_Stop(SiS_Private *SiS_Pr); +#endif + + + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c index fe29521f0..b41741153 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c @@ -1,27 +1,35 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c,v 1.9 2003/06/26 22:35:18 twini Exp $ */ /* + * SiS DGA handling + * * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK. + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * Portions from radeon_dga.c which is + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and + * VA Linux Systems Inc., Fremont, California. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the providers not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The providers make no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE PROVIDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE PROVIDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Thomas Winischhofer <thomas@winischhofer.net> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c,v 1.1 2000/06/26 10:26:15 alanh Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -35,15 +43,15 @@ #include "dgaproc.h" static Bool SIS_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, - int *, int *, int *); + int *, int *, int *); static Bool SIS_SetMode(ScrnInfoPtr, DGAModePtr); static void SIS_Sync(ScrnInfoPtr); static int SIS_GetViewport(ScrnInfoPtr); static void SIS_SetViewport(ScrnInfoPtr, int, int, int); static void SIS_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); static void SIS_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); -static void SIS_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, - unsigned long); +static void SIS_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, + unsigned long); static DGAFunctionRec SISDGAFuncs = { @@ -55,105 +63,200 @@ DGAFunctionRec SISDGAFuncs = { SIS_Sync, SIS_FillRect, SIS_BlitRect, -#if 0 - SIS_BlitTransRect -#else NULL -#endif }; -Bool -SISDGAInit(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSIS = SISPTR(pScrn); - DGAModePtr modes = NULL, newmodes = NULL, currentMode; +static +DGAFunctionRec SISDGAFuncs3xx = { + SIS_OpenFramebuffer, + NULL, + SIS_SetMode, + SIS_SetViewport, + SIS_GetViewport, + SIS_Sync, + SIS_FillRect, + SIS_BlitRect, + SIS_BlitTransRect +}; + +static DGAModePtr +SISSetupDGAMode( + ScrnInfoPtr pScrn, + DGAModePtr modes, + int *num, + int bitsPerPixel, + int depth, + Bool pixmap, + int secondPitch, + unsigned long red, + unsigned long green, + unsigned long blue, + short visualClass +){ + SISPtr pSiS = SISPTR(pScrn); + DGAModePtr newmodes = NULL, currentMode; DisplayModePtr pMode, firstMode; - int Bpp = pScrn->bitsPerPixel >> 3; - int num = 0; + int otherPitch, Bpp = bitsPerPixel >> 3; Bool oneMore; pMode = firstMode = pScrn->modes; - while(pMode) { + while (pMode) { + + otherPitch = secondPitch ? secondPitch : pMode->HDisplay; + + if(pMode->HDisplay != otherPitch) { + + newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; - if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { - newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); - oneMore = TRUE; } else { - newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); - oneMore = FALSE; + + newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } if(!newmodes) { - xfree(modes); - return FALSE; + xfree(modes); + return NULL; } modes = newmodes; SECOND_PASS: - currentMode = modes + num; - num++; - - currentMode->mode = pMode; - currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; - currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; - if(pMode->Flags & V_DBLSCAN) - currentMode->flags |= DGA_DOUBLESCAN; - if(pMode->Flags & V_INTERLACE) - currentMode->flags |= DGA_INTERLACED; - currentMode->byteOrder = pScrn->imageByteOrder; - currentMode->depth = pScrn->depth; - currentMode->bitsPerPixel = pScrn->bitsPerPixel; - currentMode->red_mask = pScrn->mask.red; - currentMode->green_mask = pScrn->mask.green; - currentMode->blue_mask = pScrn->mask.blue; - currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; - currentMode->viewportWidth = pMode->HDisplay; + currentMode = modes + *num; + (*num)++; + + currentMode->mode = pMode; + currentMode->flags = DGA_CONCURRENT_ACCESS; + if(pixmap) + currentMode->flags |= DGA_PIXMAP_AVAILABLE; + if(!pSiS->NoAccel) { + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if((pSiS->VGAEngine == SIS_300_VGA) || + (pSiS->VGAEngine == SIS_315_VGA) || + (pSiS->VGAEngine == SIS_530_VGA)) { + currentMode->flags |= DGA_BLIT_RECT_TRANS; + } + } + if (pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if (pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = depth; + currentMode->bitsPerPixel = bitsPerPixel; + currentMode->red_mask = red; + currentMode->green_mask = green; + currentMode->blue_mask = blue; + currentMode->visualClass = visualClass; + currentMode->viewportWidth = pMode->HDisplay; currentMode->viewportHeight = pMode->VDisplay; - currentMode->xViewportStep = 1; - currentMode->yViewportStep = 1; - currentMode->viewportFlags = DGA_FLIP_RETRACE; - currentMode->offset = 0; - currentMode->address = pSIS->FbBase; - - if(oneMore) { /* first one is narrow width */ - currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; - currentMode->imageWidth = pMode->HDisplay; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->xViewportStep = 1; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = pSiS->FbBase; + + if(oneMore) { + + /* first one is narrow width */ + currentMode->bytesPerScanline = (((pMode->HDisplay * Bpp) + 3) & ~3L); + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - + currentMode->maxViewportX = currentMode->imageWidth - currentMode->viewportWidth; /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; + currentMode->maxViewportY = (currentMode->imageHeight - + currentMode->viewportHeight); oneMore = FALSE; goto SECOND_PASS; + } else { - currentMode->bytesPerScanline = - ((pScrn->displayWidth * Bpp) + 3) & ~3L; - currentMode->imageWidth = pScrn->displayWidth; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; - currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - } + + currentMode->bytesPerScanline = ((otherPitch * Bpp) + 3) & ~3L; + currentMode->imageWidth = otherPitch; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = (currentMode->imageWidth - + currentMode->viewportWidth); + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = (currentMode->imageHeight - + currentMode->viewportHeight); + } pMode = pMode->next; - if(pMode == firstMode) - break; + if (pMode == firstMode) + break; + } + + return modes; +} + + +Bool +SISDGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + DGAModePtr modes = NULL; + int num = 0; + + /* 8 */ +#ifdef SISDUALHEAD + /* We don't ever use 8bpp modes in dual head mode, + * so don't offer them to DGA either + */ + if(!pSiS->DualHeadMode) { +#endif + modes = SISSetupDGAMode(pScrn, modes, &num, 8, 8, + (pScrn->bitsPerPixel == 8), + ((pScrn->bitsPerPixel != 8) + ? 0 : pScrn->displayWidth), + 0, 0, 0, PseudoColor); +#ifdef SISDUALHEAD } +#endif - pSIS->numDGAModes = num; - pSIS->DGAModes = modes; + /* 16 */ + modes = SISSetupDGAMode(pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 16) + ? 0 : pScrn->displayWidth), + 0xf800, 0x07e0, 0x001f, TrueColor); + + if((pSiS->VGAEngine == SIS_530_VGA) || (pSiS->VGAEngine == SIS_OLD_VGA)) { + /* 24 */ + modes = SISSetupDGAMode(pScrn, modes, &num, 24, 24, + (pScrn->bitsPerPixel == 24), + ((pScrn->bitsPerPixel != 24) + ? 0 : pScrn->displayWidth), + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + } + + if(pSiS->VGAEngine != SIS_OLD_VGA) { + /* 32 */ + modes = SISSetupDGAMode(pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + ((pScrn->bitsPerPixel != 32) + ? 0 : pScrn->displayWidth), + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + } - return DGAInit(pScreen, &SISDGAFuncs, modes, num); + pSiS->numDGAModes = num; + pSiS->DGAModes = modes; + + if((pSiS->VGAEngine == SIS_300_VGA) || + (pSiS->VGAEngine == SIS_315_VGA) || + (pSiS->VGAEngine == SIS_530_VGA)) { + return DGAInit(pScreen, &SISDGAFuncs3xx, modes, num); + } else { + return DGAInit(pScreen, &SISDGAFuncs, modes, num); + } } @@ -162,52 +265,63 @@ SIS_SetMode( ScrnInfoPtr pScrn, DGAModePtr pMode ){ - static int OldDisplayWidth[MAXSCREENS]; + static SISFBLayout BackupLayouts[MAXSCREENS]; int index = pScrn->pScreen->myNum; - SISPtr pSIS = SISPTR(pScrn); - - if(!pMode) { /* restore the original mode */ - /* put the ScreenParameters back */ - - pScrn->displayWidth = OldDisplayWidth[index]; - - SISSwitchMode(index, pScrn->currentMode, 0); - pSIS->DGAactive = FALSE; - } else { - if(!pSIS->DGAactive) { /* save the old parameters */ - OldDisplayWidth[index] = pScrn->displayWidth; + SISPtr pSiS = SISPTR(pScrn); - pSIS->DGAactive = TRUE; - } + if(!pMode) { /* restore the original mode */ - pScrn->displayWidth = pMode->bytesPerScanline / - (pMode->bitsPerPixel >> 3); + if(pSiS->DGAactive) { + /* put the ScreenParameters back */ + memcpy(&pSiS->CurrentLayout, &BackupLayouts[index], sizeof(SISFBLayout)); + } - SISSwitchMode(index, pMode->mode, 0); - } - - return TRUE; + pScrn->currentMode = pSiS->CurrentLayout.mode; + + (*pScrn->SwitchMode)(index, pScrn->currentMode, 0); + (*pScrn->AdjustFrame)(index, pScrn->frameX0, pScrn->frameY0, 0); + pSiS->DGAactive = FALSE; + + } else { /* set new mode */ + + if(!pSiS->DGAactive) { + /* save the old parameters */ + memcpy(&BackupLayouts[index], &pSiS->CurrentLayout, sizeof(SISFBLayout)); + pSiS->DGAactive = TRUE; + } + + pSiS->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; + pSiS->CurrentLayout.depth = pMode->depth; + pSiS->CurrentLayout.displayWidth = pMode->bytesPerScanline / (pMode->bitsPerPixel >> 3); + + (*pScrn->SwitchMode)(index, pMode->mode, 0); + /* TW: Adjust viewport to 0/0 after mode switch */ + /* This should fix the vmware-in-dualhead problems */ + (*pScrn->AdjustFrame)(index, 0, 0, 0); + } + + return TRUE; } -static int +static int SIS_GetViewport( ScrnInfoPtr pScrn ){ - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); - return pSIS->DGAViewportStatus; + return pSiS->DGAViewportStatus; } static void SIS_SetViewport( - ScrnInfoPtr pScrn, + ScrnInfoPtr pScrn, int x, int y, int flags ){ - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); - SISAdjustFrame(pScrn->pScreen->myNum, x, y, flags); - pSIS->DGAViewportStatus = 0; /* SISAdjustFrame loops until finished */ + (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags); + pSiS->DGAViewportStatus = 0; /* There are never pending Adjusts */ } static void @@ -216,12 +330,12 @@ SIS_FillRect ( int x, int y, int w, int h, unsigned long color ){ - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); - if(pSIS->AccelInfoPtr) { - (*pSIS->AccelInfoPtr->SetupForSolidFill)(pScrn, color, GXcopy, ~0); - (*pSIS->AccelInfoPtr->SubsequentSolidFillRect)(pScrn, x, y, w, h); - SET_SYNC_FLAG(pSIS->AccelInfoPtr); + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*pSiS->AccelInfoPtr->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(pSiS->AccelInfoPtr); } } @@ -229,10 +343,10 @@ static void SIS_Sync( ScrnInfoPtr pScrn ){ - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); - if(pSIS->AccelInfoPtr) { - (*pSIS->AccelInfoPtr->Sync)(pScrn); + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); } } @@ -243,22 +357,21 @@ SIS_BlitRect( int w, int h, int dstx, int dsty ){ - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); - if(pSIS->AccelInfoPtr) { - int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; - int ydir = (srcy < dsty) ? -1 : 1; + if(pSiS->AccelInfoPtr) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; - (*pSIS->AccelInfoPtr->SetupForScreenToScreenCopy)( - pScrn, xdir, ydir, GXcopy, ~0, -1); - (*pSIS->AccelInfoPtr->SubsequentScreenToScreenCopy)( - pScrn, srcx, srcy, dstx, dsty, w, h); - SET_SYNC_FLAG(pSIS->AccelInfoPtr); + (*pSiS->AccelInfoPtr->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, (CARD32)~0, -1); + (*pSiS->AccelInfoPtr->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pSiS->AccelInfoPtr); } } - -static void +static void SIS_BlitTransRect( ScrnInfoPtr pScrn, int srcx, int srcy, @@ -266,25 +379,34 @@ SIS_BlitTransRect( int dstx, int dsty, unsigned long color ){ - /* this one should be separate since the XAA function would - prohibit usage of ~0 as the key */ -} + SISPtr pSiS = SISPTR(pScrn); + if(pSiS->AccelInfoPtr) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pSiS->AccelInfoPtr->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, color); + (*pSiS->AccelInfoPtr->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pSiS->AccelInfoPtr); + } +} static Bool SIS_OpenFramebuffer( - ScrnInfoPtr pScrn, + ScrnInfoPtr pScrn, char **name, unsigned char **mem, int *size, int *offset, int *flags ){ - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); - *name = NULL; /* no special device */ - *mem = (unsigned char*)pSIS->FbAddress; - *size = pSIS->FbMapSize; + *name = NULL; /* no special device */ + *mem = (unsigned char*)pSiS->FbAddress; + *size = pSiS->maxxfbmem; *offset = 0; *flags = DGA_NEED_ROOT; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c index 0f4403af7..c689f1e5c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c @@ -1,10 +1,8 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c,v 1.25 2003/01/29 15:42:17 eich Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c,v 1.28 2003/05/21 15:15:03 twini Exp $ */ /* * DRI wrapper for 300, 540, 630, 730 - * (310/325 series experimental and incomplete) * - * taken and modified from tdfx_dri.c, mga_dri.c + * Taken and modified from tdfx_dri.c, mga_dri.c */ #include "xf86.h" @@ -31,9 +29,9 @@ while((MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ MMIO_IN16(pSiS->IOBase, 0x8240); -/* TW: Idle function for 310/325 series */ +/* TW: Idle function for 315 series */ #define Q_STATUS 0x85CC -#define SiS310Idle \ +#define SiS315Idle \ { \ while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ @@ -169,8 +167,8 @@ SISInitVisualConfigs(ScreenPtr pScreen) } pConfigs[i].auxBuffers = 0; pConfigs[i].level = 0; - pConfigs[i].visualRating = GLX_NONE; - pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = 0; pConfigs[i].transparentRed = 0; pConfigs[i].transparentGreen = 0; pConfigs[i].transparentBlue = 0; @@ -527,11 +525,11 @@ SISDRIFinishScreenInit(ScreenPtr pScreen) /* frame control */ saPriv->FrameCount = 0; - if (pSiS->VGAEngine == SIS_315_VGA) { /* 310/325 series */ + if (pSiS->VGAEngine == SIS_315_VGA) { /* 315 series */ #if 0 - *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0; /* FIXME: Where is this on the 310 series ? */ + *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0; /* FIXME: Where is this on the 315 series ? */ #endif - SiS310Idle + SiS315Idle } else { /* 300 series (and below) */ *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0; SiSIdle @@ -567,8 +565,8 @@ SISDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, */ if (pSiS->VGAEngine == SIS_315_VGA) { #if 0 - *(pSiS->IOBase + 0x8B50) = 0xff; /* FIXME: Where is this on 310 series */ - *(unsigned int *)(pSiS->IOBase + 0x8B60) = -1; /* FIXME: Where is this on 310 series */ + *(pSiS->IOBase + 0x8B50) = 0xff; /* FIXME: Where is this on 315 series */ + *(unsigned int *)(pSiS->IOBase + 0x8B60) = -1; /* FIXME: Where is this on 315 series */ #endif } else { *(pSiS->IOBase + 0x8B50) = 0xff; @@ -584,7 +582,7 @@ SISDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) SISPtr pSiS = SISPTR(pScrn); if (pSiS->VGAEngine == SIS_315_VGA) { - SiS310Idle /* 310/325 series */ + SiS315Idle /* 315 series */ } else { SiSIdle /* 300 series */ } @@ -599,7 +597,7 @@ SISDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, SISPtr pSiS = SISPTR(pScrn); if (pSiS->VGAEngine == SIS_315_VGA) { - SiS310Idle /* 310/325 series */ + SiS315Idle /* 315 series */ } else { SiSIdle /* 300 series and below */ } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c index eb89fe24b..2e548879b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c @@ -1,7 +1,9 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.86 2003/02/04 02:44:29 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.102 2003/08/10 21:25:37 twini Exp $ */ /* + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. + * + * Formerly based on old code which is * Copyright 1998,1999 by Alan Hourihane, Wigan, England. - * Parts Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -21,28 +23,36 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * - driver entirely rewritten, only basic structure taken from old code + * (except sis_dri.c, sis_shadow.c and parts of sis_dga.c; + * these were taken over) + * - 315 series (315/550/650/651/M650/652/M652/740) support + * - Xabre series (330/660/M660/760/M760) support + * - new mode switching code for 300, 315 and 330 series + * - dual head support on 300, 315 and 330 series + * - merged-framebuffer support on 300, 315 and 330 series + * - Xinerama extension for MergedFB mode + * - rewritten for 5597/5598, 6326 and 530/620 chipsets, + * - rewritten for 300/540/630/730 chipsets, + * - VESA mode switching (deprecated), + * - extended CRT2/video bridge handling support, + * - 650/740/Chrontel 7019/LVDS support (up to 1600x1200) + * - 30x/30xB/30xLV video bridge support (300, 315, 330 series) + * - entirely rewritten Xv support for 300 series + * - Xv support for 5597/5598, 6326, 530/620, 315 and 330 series + * - TV and hi-res support for the 6326 + * - Color HW cursor support for 300(emulated), 315 and 330 series + * - etc. etc. etc. + * + * This notice covers the entire driver code + * + * Authors of old code: + * Alan Hourihane, alanh@fairlite.demon.co.uk * Mike Chapman <mike@paranoia.com>, * Juanjo Santamarta <santamarta@ctv.es>, * Mitani Hiroshi <hmitani@drl.mei.co.jp> * David Thomas <davtom@dream.org.uk>. - * - * Thomas Winischhofer <thomas@winischhofer.net>: - * - 310/325 series (315/550/650/651/740/M650) support - * - (possibly incomplete) Xabre (SiS330) support - * - new mode switching code for 300, 310/325 and 330 series - * - many fixes for 300/540/630/730 chipsets, - * - many fixes for 5597/5598, 6326 and 530/620 chipsets, - * - VESA mode switching (deprecated), - * - extended CRT2/video bridge handling support, - * - dual head support on 300, 310/325 and 330 series - * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support - * - 30xB/30xLV/30xLVX video bridge support (300, 310/325, 330 series) - * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series - * - video overlay enhancements for 300 series - * - TV and hi-res support for the 6326 - * - Color HW cursor support for 300(emulated), 310/325 and 330 series - * - etc. */ #include "fb.h" @@ -68,7 +78,7 @@ #include "mipointer.h" #include "mibstore.h" - + #include "sis.h" #include "sis_regs.h" #include "sis_vb.h" @@ -80,10 +90,11 @@ #include "extensions/xf86dgastr.h" #include "globals.h" + #define DPMS_SERVER #include "extensions/dpms.h" -#ifdef XvExtension +#if (XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,0,0)) || (defined(XvExtension)) #include "xf86xv.h" #include "Xv.h" #endif @@ -131,6 +142,7 @@ static void SISBridgeRestore(ScrnInfoPtr pScrn); static void SiSEnableTurboQueue(ScrnInfoPtr pScrn); unsigned char SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode); static void SISWaitVBRetrace(ScrnInfoPtr pScrn); +Bool InRegion(int x, int y, region r); void SISWaitRetraceCRT1(ScrnInfoPtr pScrn); void SISWaitRetraceCRT2(ScrnInfoPtr pScrn); @@ -149,25 +161,47 @@ extern BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDevice ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch); -extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode); -extern USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags); extern void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr); -extern DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn); +extern void SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo); +extern void SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO); +extern DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi); #ifdef SISDUALHEAD extern BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); extern BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, - ScrnInfoPtr pScrn, DisplayModePtr mode); + ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); #endif -/* TW: For power management for 310/325 series */ -extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr); +/* For power management for 315 series */ +extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr); extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +/* Globals (yes, these ARE really required to be global) */ + #ifdef SISDUALHEAD -static int SISEntityIndex = -1; +static int SISEntityIndex = -1; +#endif + +#ifdef SISMERGED +#ifdef SISXINERAMA +static Bool SiSnoPanoramiXExtension = TRUE; +static unsigned char SiSXineramaReqCode = 0; +int SiSXineramaPixWidth = 0; +int SiSXineramaPixHeight = 0; +int SiSXineramaNumScreens = 0; +SiSXineramaData *SiSXineramadataPtr = NULL; +static int SiSXineramaGeneration; + +int SiSProcXineramaQueryVersion(ClientPtr client); +int SiSProcXineramaGetState(ClientPtr client); +int SiSProcXineramaGetScreenCount(ClientPtr client); +int SiSProcXineramaGetScreenSize(ClientPtr client); +int SiSProcXineramaIsActive(ClientPtr client); +int SiSProcXineramaQueryScreens(ClientPtr client); +int SiSSProcXineramaDispatch(ClientPtr client); +#endif #endif /* @@ -205,10 +239,9 @@ static SymTabRec SISChipsets[] = { { PCI_CHIP_SIS315H, "SIS315H" }, { PCI_CHIP_SIS315PRO, "SIS315PRO" }, { PCI_CHIP_SIS550, "SIS550" }, - { PCI_CHIP_SIS650, "SIS650/M650/651/740" }, -#ifdef INCL_SIS330 /* TW: New for SiS330 (untested) */ + { PCI_CHIP_SIS650, "SIS650/M650/651/652/M652/740" }, { PCI_CHIP_SIS330, "SIS330(Xabre)" }, -#endif + { PCI_CHIP_SIS660, "SIS660/M660/760/M760" }, { -1, NULL } }; @@ -224,9 +257,8 @@ static PciChipsets SISPciChipsets[] = { { PCI_CHIP_SIS315H, PCI_CHIP_SIS315H, RES_SHARED_VGA }, { PCI_CHIP_SIS315PRO, PCI_CHIP_SIS315PRO, RES_SHARED_VGA }, { PCI_CHIP_SIS650, PCI_CHIP_SIS650, RES_SHARED_VGA }, -#ifdef INCL_SIS330 /* TW: New for SiS330 */ { PCI_CHIP_SIS330, PCI_CHIP_SIS330, RES_SHARED_VGA }, -#endif + { PCI_CHIP_SIS660, PCI_CHIP_SIS660, RES_SHARED_VGA }, { -1, -1, RES_UNDEFINED } }; @@ -234,7 +266,10 @@ static const char *xaaSymbols[] = { "XAACopyROP", "XAACreateInfoRec", "XAADestroyInfoRec", +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) "XAAFillSolidRects", +#endif + "XAAFillMono8x8PatternRects", "XAAHelpPatternROP", "XAAInit", NULL @@ -248,6 +283,7 @@ static const char *vgahwSymbols[] = { "vgaHWInit", "vgaHWLock", "vgaHWMapMem", + "vgaHWUnmapMem", "vgaHWProtect", "vgaHWRestore", "vgaHWSave", @@ -407,7 +443,7 @@ SISGetRec(ScrnInfoPtr pScrn) * pScrn->driverPrivate is initialised to NULL, so we can check if * the allocation has already been done. */ - if (pScrn->driverPrivate != NULL) + if(pScrn->driverPrivate != NULL) return TRUE; pScrn->driverPrivate = xnfcalloc(sizeof(SISRec), 1); @@ -428,8 +464,10 @@ SISFreeRec(ScrnInfoPtr pScrn) /* TW: Just to make sure... */ if(!pSiS) return; - + +#ifdef SISDUALHEAD pSiSEnt = pSiS->entityPrivate; +#endif if(pSiS->pstate) xfree(pSiS->pstate); pSiS->pstate = NULL; @@ -460,9 +498,51 @@ SISFreeRec(ScrnInfoPtr pScrn) #ifdef SISDUALHEAD } #endif - if (pSiS->pVbe) vbeFree(pSiS->pVbe); +#ifdef SISMERGED + if(pSiS->CRT2HSync) xfree(pSiS->CRT2HSync); + pSiS->CRT2HSync = NULL; + if(pSiS->CRT2VRefresh) xfree(pSiS->CRT2VRefresh); + pSiS->CRT2VRefresh = NULL; + if(pSiS->MetaModes) xfree(pSiS->MetaModes); + pSiS->MetaModes = NULL; + if(pSiS->CRT2pScrn) { + if(pSiS->CRT2pScrn->modes) { + while(pSiS->CRT2pScrn->modes) + xf86DeleteMode(&pSiS->CRT2pScrn->modes, pSiS->CRT2pScrn->modes); + } + if(pSiS->CRT2pScrn->monitor) { + if(pSiS->CRT2pScrn->monitor->Modes) { + while(pSiS->CRT2pScrn->monitor->Modes) + xf86DeleteMode(&pSiS->CRT2pScrn->monitor->Modes, pSiS->CRT2pScrn->monitor->Modes); + } + if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC); + xfree(pSiS->CRT2pScrn->monitor); + } + xfree(pSiS->CRT2pScrn); + pSiS->CRT2pScrn = NULL; + } + if(pSiS->CRT1Modes) { + if(pSiS->CRT1Modes != pScrn->modes) { + if(pScrn->modes) { + pScrn->currentMode = pScrn->modes; + do { + DisplayModePtr p = pScrn->currentMode->next; + if(pScrn->currentMode->Private) + xfree(pScrn->currentMode->Private); + xfree(pScrn->currentMode); + pScrn->currentMode = p; + } while(pScrn->currentMode != pScrn->modes); + } + pScrn->currentMode = pSiS->CRT1CurrentMode; + pScrn->modes = pSiS->CRT1Modes; + pSiS->CRT1CurrentMode = NULL; + pSiS->CRT1Modes = NULL; + } + } +#endif + if(pSiS->pVbe) vbeFree(pSiS->pVbe); pSiS->pVbe = NULL; - if (pScrn->driverPrivate == NULL) + if(pScrn->driverPrivate == NULL) return; xfree(pScrn->driverPrivate); pScrn->driverPrivate = NULL; @@ -472,290 +552,193 @@ static void SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) { SISPtr pSiS = SISPTR(pScrn); - unsigned char extDDC_PCR=0; - unsigned char crtc17, seq1; + BOOLEAN docrt1 = TRUE, docrt2 = TRUE; + unsigned char sr1=0, cr17=0, cr63=0, sr11=0, pmreg=0, sr7=0; + unsigned char p1_13=0, p2_0=0, oldpmreg=0; + BOOLEAN backlight = TRUE; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "SISDisplayPowerManagementSet(%d)\n",PowerManagementMode); - /* unlock registers */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) docrt2 = FALSE; + else docrt1 = FALSE; + } +#endif + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - /* Read CR17 */ - inSISIDXREG(SISCR, 0x17, crtc17); - - /* Read SR1 */ - inSISIDXREG(SISSR, 0x01, seq1); - - if(pSiS->VBFlags & CRT2_LCD) { - if(((pSiS->VGAEngine == SIS_300_VGA) && - (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || - ((pSiS->VGAEngine == SIS_315_VGA) && - ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { - /* Read Power Control Register (SR11) */ - inSISIDXREG(SISSR, 0x11, extDDC_PCR); - /* if not blanked, obtain state of LCD blank flags set by BIOS */ - if(!pSiS->Blank) { - pSiS->LCDon = extDDC_PCR; - } - /* erase LCD blank flags */ - extDDC_PCR &= ~0x0C; - } + if(docrt2) { + if(pSiS->VBFlags & CRT2_LCD) { + if(((pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->VBFlags & (VB_301|VB_30xBDH|VB_LVDS))) || + ((pSiS->VGAEngine == SIS_315_VGA) && + ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->BlankCRT2) inSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } else +#endif + if(!pSiS->Blank) inSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + } } switch (PowerManagementMode) { case DPMSModeOn: /* HSync: On, VSync: On */ - - pSiS->Blank = FALSE; - seq1 &= ~0x20; - crtc17 |= 0x80; - if(pSiS->VBFlags & CRT2_LCD) { - if(pSiS->VGAEngine == SIS_315_VGA) { - if(pSiS->VBFlags & VB_CHRONTEL) { - SiS_Chrontel701xBLOn(pSiS->SiS_Pr); - } else if(pSiS->VBFlags & VB_LVDS) { - extDDC_PCR |= (pSiS->LCDon & 0x0C); - } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); - } - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); - } else { - extDDC_PCR |= (pSiS->LCDon & 0x0C); - } - } - } + if(docrt1) pSiS->Blank = FALSE; +#ifdef SISDUALHEAD + else pSiS->BlankCRT2 = FALSE; +#endif + sr1 = 0x00; + cr17 = 0x80; + pmreg = 0x00; + cr63 = 0x00; + sr7 = 0x10; + sr11 = (pSiS->LCDon & 0x0C); + p2_0 = 0x20; + p1_13 = 0x00; + backlight = TRUE; break; - case DPMSModeStandby: /* HSync: Off, VSync: On */ case DPMSModeSuspend: /* HSync: On, VSync: Off */ + if(docrt1) pSiS->Blank = TRUE; +#ifdef SISDUALHEAD + else pSiS->BlankCRT2 = TRUE; +#endif + sr1 = 0x20; + cr17 = 0x80; + pmreg = 0x80; + cr63 = 0x40; + sr7 = 0x00; + sr11 = 0x08; + p2_0 = 0x40; + p1_13 = 0x80; + backlight = FALSE; + break; - pSiS->Blank = TRUE; - seq1 |= 0x20 ; - if(pSiS->VBFlags & CRT2_LCD) { - if(pSiS->VGAEngine == SIS_315_VGA) { - if(pSiS->VBFlags & VB_CHRONTEL) { - SiS_Chrontel701xBLOff(pSiS->SiS_Pr); - } else if(pSiS->VBFlags & VB_LVDS) { - extDDC_PCR |= 0x08; - } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); - } - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); - } else { - extDDC_PCR |= 0x08; - } - } - } + case DPMSModeStandby: /* HSync: Off, VSync: On */ + if(docrt1) pSiS->Blank = TRUE; +#ifdef SISDUALHEAD + else pSiS->BlankCRT2 = TRUE; +#endif + sr1 = 0x20; + cr17 = 0x80; + pmreg = 0x40; + cr63 = 0x40; + sr7 = 0x00; + sr11 = 0x08; + p2_0 = 0x80; + p1_13 = 0x40; + backlight = FALSE; break; case DPMSModeOff: /* HSync: Off, VSync: Off */ - - pSiS->Blank = TRUE; - seq1 |= 0x20; - if(pSiS->VGAEngine == SIS_300_VGA || - pSiS->VGAEngine == SIS_315_VGA) { - /* TW: We can't switch off CRT1 if bridge is in slavemode */ - if(pSiS->VBFlags & CRT2_ENABLE) { - if(!(SiSBridgeIsInSlaveMode(pScrn))) crtc17 &= ~0x80; - } else crtc17 &= ~0x80; - } else { - crtc17 &= ~0x80; - } - if(pSiS->VBFlags & CRT2_LCD) { - if(pSiS->VGAEngine == SIS_315_VGA) { - if(pSiS->VBFlags & VB_CHRONTEL) { - SiS_Chrontel701xBLOff(pSiS->SiS_Pr); - } else if(pSiS->VBFlags & VB_LVDS) { - extDDC_PCR |= 0x0C; - } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); - } - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); - } else { - extDDC_PCR |= 0x0C; - } - } - } + if(docrt1) pSiS->Blank = TRUE; +#ifdef SISDUALHEAD + else pSiS->BlankCRT2 = TRUE; +#endif + sr1 = 0x20; + cr17 = 0x00; + pmreg = 0xc0; + cr63 = 0x40; + sr7 = 0x00; + sr11 = 0x08; + p2_0 = 0xc0; + p1_13 = 0xc0; + backlight = FALSE; break; + default: + return; } - outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */ - - outSISIDXREG(SISCR, 0x17, crtc17); - - if(pSiS->VBFlags & CRT2_LCD) { - if(((pSiS->VGAEngine == SIS_300_VGA) && - (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || - ((pSiS->VGAEngine == SIS_315_VGA) && - ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { - outSISIDXREG(SISSR, 0x11, extDDC_PCR); - } + if(docrt2) { + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { + if(backlight) { + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & VB_CHRONTEL) { + if(backlight) { + SiS_Chrontel701xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + SiS_Chrontel701xBLOff(pSiS->SiS_Pr); + } + } + } + } } - outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ - usleep(10000); - outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ - -} - -#ifdef SISDUALHEAD -/* TW: DPMS for dual head mode */ -static void -SISDisplayPowerManagementSetDH(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) -{ - SISPtr pSiS = SISPTR(pScrn); - unsigned char crtc17 = 0; - unsigned char extDDC_PCR=0; - unsigned char seq1 = 0; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "SISDisplayPowerManagementSetDH(%d)\n",PowerManagementMode); - - /* unlock registers */ -#ifdef UNLOCK_ALWAYS - sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); -#endif - - if (pSiS->SecondHead) { + if(docrt1) { + setSISIDXREG(SISSR, 0x01, ~0x20, sr1); /* Set/Clear "Display On" bit */ - /* TW: Second (slave) head is always CRT1 */ - - /* Read CR17 and SR01 */ - inSISIDXREG(SISCR, 0x17, crtc17); - inSISIDXREG(SISSR, 0x01, seq1); - - switch (PowerManagementMode) - { - case DPMSModeOn: /* HSync: On, VSync: On */ - seq1 &= ~0x20 ; - crtc17 |= 0x80; - pSiS->BlankCRT1 = FALSE; - break; - - case DPMSModeStandby: /* HSync: Off, VSync: On */ - case DPMSModeSuspend: /* HSync: On, VSync: Off */ - seq1 |= 0x20; - pSiS->BlankCRT1 = TRUE; - break; - - case DPMSModeOff: /* HSync: Off, VSync: Off */ - seq1 |= 0x20 ; - pSiS->BlankCRT1 = TRUE; - crtc17 &= ~0x80; - break; - } - outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ - - outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */ - - usleep(10000); - - outSISIDXREG(SISCR, 0x17, crtc17); - - outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ - - } else { - - /* TW: Master head is always CRT2 */ - - /* TV can not be managed */ - if(!(pSiS->VBFlags & CRT2_LCD)) return; - - if(((pSiS->VGAEngine == SIS_300_VGA) && - (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || - ((pSiS->VGAEngine == SIS_315_VGA) && - ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { - /* Read Power Control Register (SR11) */ - inSISIDXREG(SISSR, 0x11, extDDC_PCR); - /* if not blanked obtain state of LCD blank flags set by BIOS */ - if(!pSiS->BlankCRT2) { - pSiS->LCDon = extDDC_PCR; - } - /* erase LCD blank flags */ - extDDC_PCR &= ~0xC; - } - - switch (PowerManagementMode) { - - case DPMSModeOn: - pSiS->BlankCRT2 = FALSE; - if(pSiS->VGAEngine == SIS_315_VGA) { - if(pSiS->VBFlags & VB_CHRONTEL) { - SiS_Chrontel701xBLOn(pSiS->SiS_Pr); - } else if(pSiS->VBFlags & VB_LVDS) { - extDDC_PCR |= (pSiS->LCDon & 0x0C); - } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext); - } - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext); - } else { - extDDC_PCR |= (pSiS->LCDon & 0x0C); - } - } - break; - - case DPMSModeStandby: - case DPMSModeSuspend: - pSiS->BlankCRT2 = TRUE; - if(pSiS->VGAEngine == SIS_315_VGA) { - if(pSiS->VBFlags & VB_CHRONTEL) { - SiS_Chrontel701xBLOff(pSiS->SiS_Pr); - } else if(pSiS->VBFlags & VB_LVDS) { - extDDC_PCR |= 0x08; - } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); - } - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); - } else { - extDDC_PCR |= 0x08; - } + switch(pSiS->VGAEngine) { + case SIS_OLD_VGA: + case SIS_530_VGA: + inSISIDXREG(SISSR, 0x11, oldpmreg); + setSISIDXREG(SISCR, 0x17, 0x7f, cr17); + setSISIDXREG(SISSR, 0x11, 0x3f, pmreg); + break; + case SIS_315_VGA: + if(!pSiS->CRT1off) { + setSISIDXREG(SISCR, 0x63, 0xbf, cr63); + setSISIDXREG(SISSR, 0x07, 0xef, sr7); } - break; - - case DPMSModeOff: - pSiS->BlankCRT2 = TRUE; - if(pSiS->VGAEngine == SIS_315_VGA) { - if(pSiS->VBFlags & VB_CHRONTEL) { - SiS_Chrontel701xBLOff(pSiS->SiS_Pr); - } else if(pSiS->VBFlags & VB_LVDS) { - extDDC_PCR |= 0x0C; - } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); - } - } else if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); - } else { - extDDC_PCR |= 0x0C; - } - } - break; - } + /* fall through */ + default: + inSISIDXREG(SISSR, 0x1f, oldpmreg); + if(!pSiS->CRT1off) { + setSISIDXREG(SISSR, 0x1f, 0x3f, pmreg); + } + /* TODO: Check if Chrontel TV is active and in slave mode, + * don't go into power-saving mode this in this case! + */ + } + oldpmreg &= 0xc0; + } - if(((pSiS->VGAEngine == SIS_300_VGA) && - (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || - ((pSiS->VGAEngine == SIS_315_VGA) && - ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { - outSISIDXREG(SISSR, 0x11, extDDC_PCR); - } + if(docrt2) { + if(pSiS->VBFlags & CRT2_LCD) { + if(((pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->VBFlags & (VB_301|VB_30xBDH|VB_LVDS))) || + ((pSiS->VGAEngine == SIS_315_VGA) && + ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { + setSISIDXREG(SISSR, 0x11, ~0x0c, sr11); + } + if(pSiS->VGAEngine == SIS_300_VGA) { + if((pSiS->VBFlags & (VB_301B|VB_302B)) && + (!(pSiS->VBFlags & VB_30xBDH))) { + setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13); + } + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if((pSiS->VBFlags & (VB_301B|VB_302B)) && + (!(pSiS->VBFlags & VB_30xBDH))) { + setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0); + } + } + } else if(pSiS->VBFlags & CRT2_VGA) { + if(pSiS->VBFlags & (VB_301B|VB_302B)) { + setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0); + } + } + } + if((docrt1) && (pmreg != oldpmreg)) { + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ } + } -#endif + /* Mandatory */ static void @@ -780,6 +763,65 @@ SIS1bppColorMap(ScrnInfoPtr pScrn) outSISREG(SISCOLDATA, 0x3f); } +#if 0 +/* This won't work as long as noone added the symbols to the symlist */ +static void +SISCalculateGammaRamp(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + int i, j, nramp; + unsigned short *ramp[3]; + float gamma_max[3], gamma_prescale[3], framp; + + gamma_max[0] = (float)pSiS->GammaBriR / 1000; + gamma_max[1] = (float)pSiS->GammaBriG / 1000; + gamma_max[2] = (float)pSiS->GammaBriB / 1000; + gamma_prescale[0] = (float)pSiS->GammaPBriR / 1000; + gamma_prescale[1] = (float)pSiS->GammaPBriG / 1000; + gamma_prescale[2] = (float)pSiS->GammaPBriB / 1000; + + if(!(nramp = xf86GetGammaRampSize(pScrn->pScreen))) return; + + for(i=0; i<3; i++) { + ramp[i] = (unsigned short *)xalloc(nramp * sizeof(unsigned short)); + if(!ramp[i]) { + if(ramp[0]) { xfree(ramp[0]); ramp[0] = NULL; } + if(ramp[1]) { xfree(ramp[1]); ramp[1] = NULL; } + return; + } + } + + for(i = 0; i < 3; i++) { + int fullscale = 65535 * gamma_max[i]; + float dramp = 1. / (nramp - 1); + float invgamma=0.0, v; + + switch(i) { + case 0: invgamma = 1. / pScrn->gamma.red; break; + case 1: invgamma = 1. / pScrn->gamma.green; break; + case 2: invgamma = 1. / pScrn->gamma.blue; break; + } + + for(j = 0; j < nramp; j++) { + framp = pow(gamma_prescale[i] * j * dramp, invgamma); + + v = (fullscale < 0) ? (65535 + fullscale * framp) : + fullscale * framp; + if(v < 0) v = 0; + else if(v > 65535) v = 65535; + ramp[i][j] = (unsigned short)v; + } + } + + xf86ChangeGammaRamp(pScrn->pScreen, nramp, ramp[0], ramp[1], ramp[2]); + + xfree(ramp[0]); + xfree(ramp[1]); + xfree(ramp[2]); + ramp[0] = ramp[1] = ramp[2] = NULL; +} +#endif + /* Mandatory */ static Bool SISProbe(DriverPtr drv, int flags) @@ -811,7 +853,7 @@ SISProbe(DriverPtr drv, int flags) * specified. */ - if ((numDevSections = xf86MatchDevice(SIS_DRIVER_NAME, + if((numDevSections = xf86MatchDevice(SIS_DRIVER_NAME, &devSections)) <= 0) { /* * There's no matching device section in the config file, so quit @@ -830,7 +872,7 @@ SISProbe(DriverPtr drv, int flags) * All of the cards this driver supports are PCI, so the "probing" just * amounts to checking the PCI data that the server has already collected. */ - if (xf86GetPciVideoInfo() == NULL) { + if(xf86GetPciVideoInfo() == NULL) { /* * We won't let anything in the config file override finding no * PCI video cards at all. This seems reasonable now, but we'll see. @@ -844,12 +886,12 @@ SISProbe(DriverPtr drv, int flags) /* Free it since we don't need that list after this */ xfree(devSections); - if (numUsed <= 0) + if(numUsed <= 0) return FALSE; - if (flags & PROBE_DETECT) + if(flags & PROBE_DETECT) foundScreen = TRUE; - else for (i = 0; i < numUsed; i++) { + else for(i = 0; i < numUsed; i++) { ScrnInfoPtr pScrn; #ifdef SISDUALHEAD EntityInfoPtr pEnt; @@ -858,7 +900,7 @@ SISProbe(DriverPtr drv, int flags) /* Allocate a ScrnInfoRec and claim the slot */ pScrn = NULL; - if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + if((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], SISPciChipsets, NULL, NULL, NULL, NULL, NULL))) { /* Fill in what we can of the ScrnInfoRec */ @@ -879,21 +921,20 @@ SISProbe(DriverPtr drv, int flags) #ifdef SISDUALHEAD pEnt = xf86GetEntityInfo(usedChips[i]); - /* TW: I assume these chipsets as - basically - dual head capable. */ - if (pEnt->chipset == PCI_CHIP_SIS630 || pEnt->chipset == PCI_CHIP_SIS540 || - pEnt->chipset == PCI_CHIP_SIS650 || pEnt->chipset == PCI_CHIP_SIS550 || - pEnt->chipset == PCI_CHIP_SIS315 || pEnt->chipset == PCI_CHIP_SIS315H || - pEnt->chipset == PCI_CHIP_SIS315PRO || pEnt->chipset == PCI_CHIP_SIS330 || - pEnt->chipset == PCI_CHIP_SIS300) { + if(pEnt->chipset == PCI_CHIP_SIS630 || pEnt->chipset == PCI_CHIP_SIS540 || + pEnt->chipset == PCI_CHIP_SIS650 || pEnt->chipset == PCI_CHIP_SIS550 || + pEnt->chipset == PCI_CHIP_SIS315 || pEnt->chipset == PCI_CHIP_SIS315H || + pEnt->chipset == PCI_CHIP_SIS315PRO || pEnt->chipset == PCI_CHIP_SIS330 || + pEnt->chipset == PCI_CHIP_SIS300 || pEnt->chipset == PCI_CHIP_SIS660) { SISEntPtr pSiSEnt = NULL; DevUnion *pPriv; xf86SetEntitySharable(usedChips[i]); - if (SISEntityIndex < 0) + if(SISEntityIndex < 0) SISEntityIndex = xf86AllocateEntityPrivateIndex(); pPriv = xf86GetEntityPrivate(pScrn->entityList[0], SISEntityIndex); - if (!pPriv->ptr) { + if(!pPriv->ptr) { pPriv->ptr = xnfcalloc(sizeof(SISEntRec), 1); pSiSEnt = pPriv->ptr; pSiSEnt->lastInstance = -1; @@ -922,8 +963,8 @@ SISProbe(DriverPtr drv, int flags) } -/* TW: If monitor section has no HSync/VRefresh data, - * derive it from DDC data. +/* If monitor section has no HSync/VRefresh data, + * derive it from DDC data. */ static void SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag) @@ -961,19 +1002,19 @@ SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag) }; /* "Future modes"; we only check the really high ones */ const myddcstdmodes mystdmodes[8] = { - { 1280, 1024, 85, 91.1 }, - { 1600, 1200, 60, 75.0 }, - { 1600, 1200, 65, 81.3 }, - { 1600, 1200, 70, 87.5 }, - { 1600, 1200, 75, 93.8 }, + { 1280, 1024, 85, 91.1 }, + { 1600, 1200, 60, 75.0 }, + { 1600, 1200, 65, 81.3 }, + { 1600, 1200, 70, 87.5 }, + { 1600, 1200, 75, 93.8 }, { 1600, 1200, 85, 106.3 }, - { 1920, 1440, 60, 90.0 }, + { 1920, 1440, 60, 90.0 }, { 1920, 1440, 75, 112.5 } }; if(flag) { /* HSync */ - for (i = 0; i < 4; i++) { - if (ddc->det_mon[i].type == DS_RANGES) { + for(i = 0; i < 4; i++) { + if(ddc->det_mon[i].type == DS_RANGES) { mon->nHsync = 1; mon->hsync[0].lo = ddc->det_mon[i].section.ranges.min_h; mon->hsync[0].hi = ddc->det_mon[i].section.ranges.max_h; @@ -1063,21 +1104,856 @@ SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag) } } +/* TW: Some helper functions for MergedFB mode */ + +#ifdef SISMERGED + +/* Helper function for CRT2 monitor vrefresh/hsync options + * (Code base from mga driver) + */ +static int +SiSStrToRanges(range *r, char *s) +{ + float num = 0.0; + int rangenum = 0; + Bool gotdash = FALSE; + Bool nextdash = FALSE; + char* strnum = NULL; + do { + switch(*s) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + if(strnum == NULL) { + strnum = s; + gotdash = nextdash; + nextdash = FALSE; + } + break; + case '-': + case ' ': + case 0: + if(strnum == NULL) break; + if(strnum != NULL) sscanf(strnum,"%f",&num); + if(gotdash) + r[rangenum - 1].hi = num; + else { + r[rangenum].lo = num; + r[rangenum].hi = num; + rangenum++; + } + strnum = NULL; + if(*s == '-') nextdash = (rangenum != 0); + break; + default : + return 0; + } + } while(*(s++) != 0); + + return rangenum; +} + +/* Copy and link two modes form merged-fb mode + * (Code base taken from mga driver) + * Copys mode i, links the result to dest, and returns it. + * Links i and j in Private record. + * If dest is NULL, return value is copy of i linked to itself. + */ +static DisplayModePtr +SiSCopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest, + DisplayModePtr i, DisplayModePtr j, + SiSScrn2Rel srel) +{ +#ifdef SISXINERAMA + SISPtr pSiS = SISPTR(pScrn); +#endif + DisplayModePtr mode; + int dx = 0,dy = 0; + + mode = xalloc(sizeof(DisplayModeRec)); + memcpy(mode, i, sizeof(DisplayModeRec)); + mode->Private = xalloc(sizeof(SiSMergedDisplayModeRec)); + ((SiSMergedDisplayModePtr)mode->Private)->CRT1 = i; + ((SiSMergedDisplayModePtr)mode->Private)->CRT2 = j; + ((SiSMergedDisplayModePtr)mode->Private)->CRT2Position = srel; + mode->PrivSize = 0; + + switch(srel) { + case sisLeftOf: + case sisRightOf: + dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay) - mode->HDisplay; + dy = min(pScrn->virtualY, max(i->VDisplay,j->VDisplay)) - mode->VDisplay; +#ifdef SISXINERAMA + pSiS->AtLeastOneNonClone = TRUE; +#endif + break; + case sisAbove: + case sisBelow: + dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay) - mode->VDisplay; + dx = min(pScrn->virtualX, max(i->HDisplay,j->HDisplay)) - mode->HDisplay; +#ifdef SISXINERAMA + pSiS->AtLeastOneNonClone = TRUE; +#endif + break; + case sisClone: + dx = min(pScrn->virtualX, max(i->HDisplay,j->HDisplay)) - mode->HDisplay; + dy = min(pScrn->virtualY, max(i->VDisplay,j->VDisplay)) - mode->VDisplay; + break; + } + mode->HDisplay += dx; + mode->HSyncStart += dx; + mode->HSyncEnd += dx; + mode->HTotal += dx; + mode->VDisplay += dy; + mode->VSyncStart += dy; + mode->VSyncEnd += dy; + mode->VTotal += dy; + mode->Clock = 0; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Merged %dx%d and %dx%d to %dx%d (Virtual %d %d)\n", + i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay, + mode->HDisplay, mode->VDisplay, + pScrn->virtualX, pScrn->virtualY); + + mode->next = mode; + mode->prev = mode; + + if(dest) { + mode->next = dest->next; /* Insert node after "dest" */ + dest->next->prev = mode; + mode->prev = dest; + dest->next = mode; + } + + return mode; +} + +/* Helper function to find a mode from a given name + * (Code base taken from mga driver) + */ +static DisplayModePtr +SiSGetModeFromName(char* str, DisplayModePtr i) +{ + DisplayModePtr c = i; + if(!i) return NULL; + do { + if(strcmp(str, c->name) == 0) return c; + c = c->next; + } while(c != i); + return NULL; +} + +/* Generate the merged-fb mode modelist + * (Code base taken from mga driver) + */ +static DisplayModePtr +SiSGenerateModeList(ScrnInfoPtr pScrn, char* str, + DisplayModePtr i, DisplayModePtr j, + SiSScrn2Rel srel) +{ +#ifdef SISXINERAMA + SISPtr pSiS = SISPTR(pScrn); +#endif + char* strmode = str; + char modename[256]; + Bool gotdash = FALSE; + SiSScrn2Rel sr; + DisplayModePtr mode1 = NULL; + DisplayModePtr mode2 = NULL; + DisplayModePtr result = NULL; + +#ifdef SISXINERAMA + pSiS->AtLeastOneNonClone = FALSE; +#endif + + do { + switch(*str) { + case 0: + case '-': + case ' ': + if((strmode != str)) { + + strncpy(modename, strmode, str - strmode); + modename[str - strmode] = 0; + + if(gotdash) { + if(mode1 == NULL) return NULL; + mode2 = SiSGetModeFromName(modename, j); + if(!mode2) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Mode \"%s\" is not a supported mode for CRT2\n", modename); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Skipping metamode \"%s-%s\".\n", mode1->name, modename); + mode1 = NULL; + } + } else { + mode1 = SiSGetModeFromName(modename, i); + if(!mode1) { + char* tmps = str; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Mode \"%s\" is not a supported mode for CRT1\n", modename); + gotdash = FALSE; + while(*tmps == ' ') tmps++; + if(*tmps == '-') { /* skip the next mode */ + tmps++; + while((*tmps == ' ') && (*tmps != 0)) tmps++; /* skip spaces */ + while((*tmps != ' ') && (*tmps != '-') && (*tmps != 0)) tmps++; /* skip modename */ + strncpy(modename,strmode,tmps - strmode); + modename[tmps - strmode] = 0; + str = tmps-1; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Skipping metamode \"%s\".\n", modename); + mode1 = NULL; + } + } + gotdash = FALSE; + } + strmode = str + 1; + gotdash |= (*str == '-'); + + if(*str != 0) break; + /* Fall through otherwise */ + + default: + if(!gotdash && mode1) { + sr = srel; + if(!mode2) { + mode2 = SiSGetModeFromName(mode1->name, j); + sr = sisClone; + } + if(!mode2) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Mode: \"%s\" is not a supported mode for CRT2\n", mode1->name); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Skipping metamode \"%s\".\n", modename); + mode1 = NULL; + } else { + result = SiSCopyModeNLink(pScrn, result, mode1, mode2, sr); + mode1 = NULL; + mode2 = NULL; + } + } + break; + + } + + } while(*(str++) != 0); + + return result; +} + +/* Pseudo-Xinerama extension for MergedFB mode */ +#ifdef SISXINERAMA + +static void +SiSUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1) +{ + SISPtr pSiS = SISPTR(pScrn1); + ScrnInfoPtr pScrn2 = NULL; + int crt1scrnnum = 0, crt2scrnnum = 1; + int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0; + DisplayModePtr currentMode, firstMode; + Bool infochanged = FALSE; + + if(!pSiS->MergedFB) return; + + if(SiSnoPanoramiXExtension) return; + + if(!SiSXineramadataPtr) { + xf86DrvMsg(pScrn1->scrnIndex, X_ERROR, + "Internal error: SiSUpdateXineramaScreenInfo(): SiSXineramadataPtr is NULL\n"); + return; + } + + if(pSiS->CRT2IsScrn0) { + crt1scrnnum = 1; + crt2scrnnum = 0; + } + + pScrn2 = pSiS->CRT2pScrn; + + /* Attention: Usage of RandR may lead into virtual X and Y values + * actually smaller than our MetaModes! To avoid this, we calculate + * the maxCRT fields here (and not somewhere else, like in CopyNLink) + */ + + if((pSiS->SiSXineramaVX != pScrn1->virtualX) || (pSiS->SiSXineramaVY != pScrn1->virtualY)) { + + if(!(pScrn1->modes)) { + xf86DrvMsg(pScrn1->scrnIndex, X_ERROR, + "Internal error: SiSUpdateXineramaScreenInfo(): pScrn->modes is NULL\n"); + return; + } + + pSiS->maxCRT1_X1 = pSiS->maxCRT1_X2 = 0; + pSiS->maxCRT1_Y1 = pSiS->maxCRT1_Y2 = 0; + pSiS->maxCRT2_X1 = pSiS->maxCRT2_X2 = 0; + pSiS->maxCRT2_Y1 = pSiS->maxCRT2_Y2 = 0; + pSiS->maxClone_X1 = pSiS->maxClone_X2 = 0; + pSiS->maxClone_Y1 = pSiS->maxClone_Y2 = 0; + + currentMode = firstMode = pScrn1->modes; + + do { + + DisplayModePtr p = currentMode->next; + DisplayModePtr i = ((SiSMergedDisplayModePtr)currentMode->Private)->CRT1; + DisplayModePtr j = ((SiSMergedDisplayModePtr)currentMode->Private)->CRT2; + SiSScrn2Rel srel = ((SiSMergedDisplayModePtr)currentMode->Private)->CRT2Position; + + if((i->HDisplay <= pScrn1->virtualX) && (j->HDisplay <= pScrn1->virtualX) && + (i->VDisplay <= pScrn1->virtualY) && (j->VDisplay <= pScrn1->virtualY)) { + + if(srel != sisClone) { + if(pSiS->maxCRT1_X1 <= i->HDisplay) { + pSiS->maxCRT1_X1 = i->HDisplay; /* Largest CRT1 mode */ + if(pSiS->maxCRT1_X2 < j->HDisplay) { + pSiS->maxCRT1_X2 = j->HDisplay; /* Largest X of CRT2 mode displayed with largest CRT1 mode */ + } + } + if(pSiS->maxCRT2_X2 <= j->HDisplay) { + pSiS->maxCRT2_X2 = j->HDisplay; /* Largest CRT2 mode */ + if(pSiS->maxCRT2_X1 < i->HDisplay) { + pSiS->maxCRT2_X1 = i->HDisplay; /* Largest X of CRT1 mode displayed with largest CRT2 mode */ + } + } + if(pSiS->maxCRT1_Y1 <= i->VDisplay) { + pSiS->maxCRT1_Y1 = i->VDisplay; + if(pSiS->maxCRT1_Y2 < j->VDisplay) { + pSiS->maxCRT1_Y2 = j->VDisplay; + } + } + if(pSiS->maxCRT2_Y2 <= j->VDisplay) { + pSiS->maxCRT2_Y2 = j->VDisplay; + if(pSiS->maxCRT2_Y1 < i->VDisplay) { + pSiS->maxCRT2_Y1 = i->VDisplay; + } + } + } else { + if(pSiS->maxClone_X1 < i->HDisplay) { + pSiS->maxClone_X1 = i->HDisplay; + } + if(pSiS->maxClone_X2 < j->HDisplay) { + pSiS->maxClone_X2 = j->HDisplay; + } + if(pSiS->maxClone_Y1 < i->VDisplay) { + pSiS->maxClone_Y1 = i->VDisplay; + } + if(pSiS->maxClone_Y2 < j->VDisplay) { + pSiS->maxClone_Y2 = j->VDisplay; + } + } + } + currentMode = p; + + } while((currentMode) && (currentMode != firstMode)); + + pSiS->SiSXineramaVX = pScrn1->virtualX; + pSiS->SiSXineramaVY = pScrn1->virtualY; + infochanged = TRUE; + + } + + /* leftof + + V 1: + CRT2: x = 0 + y = 0 + w = (maxCRT2 X) + h = (virtual Y) + CRT1: x = (virtual X) - (maxCRT1 X) + y = 0 + w = (maxCRT1 X) + h = (virtual Y) + + V 2: + CRT2: x = 0 + y = 0 + w = max CRT2 mode X + h = virtual Y size + CRT1: x = (max) CRT2 mode X von dem Metamode, wo CRT1 mode maximal breit ist + y = 0 + w = max CRT1 mode X + h = virtual Y size + + V 3: (current) + CRT1: x = (maxCRT2 X von dem MMode, wo maxCRT1 X) + y = 0 + w = (virtual X) - x + h = (virtual Y) + CRT2: x = 0 + y = 0 + w = (virtual X) - (maxCRT1 X von dem MMode, wo maxCRT2 X) + h = (virtual Y) + + */ + + switch(pSiS->CRT2Position) { + case sisLeftOf: /* V 1 */ + x1 = min(pSiS->maxCRT1_X2, pScrn1->virtualX - pSiS->maxCRT1_X1); /* pScrn1->virtualX - pSiS->maxCRT1_X1; */ + if(x1 < 0) x1 = 0; + y1 = 0; /* 0; */ + w1 = pScrn1->virtualX - x1; /* pSiS->maxCRT1_X1; */ + h1 = pScrn1->virtualY; /* pScrn1->virtualY; */ + x2 = 0; /* 0; */ + y2 = 0; /* 0; */ + w2 = max(pSiS->maxCRT2_X2, pScrn1->virtualX - pSiS->maxCRT2_X1); /* pSiS->maxCRT2_X2; */ + if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX; + h2 = pScrn1->virtualY; /* pScrn1->virtualY; */ + break; + case sisRightOf: + x1 = 0; /* 0; */ + y1 = 0; /* 0; */ + w1 = max(pSiS->maxCRT1_X1, pScrn1->virtualX - pSiS->maxCRT1_X2); /* pSiS->maxCRT1_X1; */ + if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX; + h1 = pScrn1->virtualY; /* pScrn1->virtualY; */ + x2 = min(pSiS->maxCRT2_X1, pScrn1->virtualX - pSiS->maxCRT2_X2); /* pScrn1->virtualX - pSiS->maxCRT2_X2; */ + if(x2 < 0) x2 = 0; + y2 = 0; /* 0; */ + w2 = pScrn1->virtualX - x2; /* pSiS->maxCRT2_X2; */ + h2 = pScrn1->virtualY; /* pScrn1->virtualY; */ + break; + case sisAbove: + x1 = 0; /* 0; */ + y1 = min(pSiS->maxCRT1_Y2, pScrn1->virtualY - pSiS->maxCRT1_Y1); /* pScrn1->virtualY - pSiS->maxCRT1_Y1; */ + if(y1 < 0) y1 = 0; + w1 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h1 = pScrn1->virtualY - y1; /* pSiS->maxCRT1_Y1; */ + x2 = 0; /* 0; */ + y2 = 0; /* 0; */ + w2 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h2 = max(pSiS->maxCRT2_Y2, pScrn1->virtualY - pSiS->maxCRT2_Y1); /* pSiS->maxCRT2_Y2; */ + if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY; + break; + case sisBelow: + x1 = 0; /* 0; */ + y1 = 0; /* 0; */ + w1 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h1 = max(pSiS->maxCRT1_Y1, pScrn1->virtualY - pSiS->maxCRT1_Y2); /* pSiS->maxCRT1_Y1; */ + if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY; + x2 = 0; /* 0; */ + y2 = min(pSiS->maxCRT2_Y1, pScrn1->virtualY - pSiS->maxCRT2_Y2); /* pScrn1->virtualY - pSiS->maxCRT2_Y2; */ + if(y2 < 0) y2 = 0; + w2 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h2 = pScrn1->virtualY - y2; /* pSiS->maxCRT2_Y2; */ + break; + default: + xf86DrvMsg(pScrn1->scrnIndex, X_ERROR, + "Internal error: UpdateXineramaInfo(): unsupported CRT2Position (%d)\n", + pSiS->CRT2Position); + } + SiSXineramadataPtr[crt1scrnnum].x = x1; + SiSXineramadataPtr[crt1scrnnum].y = y1; + SiSXineramadataPtr[crt1scrnnum].width = w1; + SiSXineramadataPtr[crt1scrnnum].height = h1; + SiSXineramadataPtr[crt2scrnnum].x = x2; + SiSXineramadataPtr[crt2scrnnum].y = y2; + SiSXineramadataPtr[crt2scrnnum].width = w2; + SiSXineramadataPtr[crt2scrnnum].height = h2; + + if(infochanged) { + xf86DrvMsg(pScrn1->scrnIndex, X_INFO, + "Pseudo-Xinerama: CRT1 (Screen %d) (%d,%d)-(%d,%d)\n", + crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1); + xf86DrvMsg(pScrn1->scrnIndex, X_INFO, + "Pseudo-Xinerama: CRT2 (Screen %d) (%d,%d)-(%d,%d)\n", + crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1); + } +} + +/* Proc */ + +int +SiSProcXineramaQueryVersion(ClientPtr client) +{ + xPanoramiXQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = SIS_XINERAMA_MAJOR_VERSION; + rep.minorVersion = SIS_XINERAMA_MINOR_VERSION; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +int +SiSProcXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !SiSnoPanoramiXExtension; + if(client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.state, n); + } + WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep); + return client->noClientException; +} + +int +SiSProcXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = SiSXineramaNumScreens; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.ScreenCount, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); + return client->noClientException; +} + +int +SiSProcXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin; + xPanoramiXGetScreenSizeReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + pWin = LookupWindow (stuff->window, client); + if(!pWin) return BadWindow; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.width = SiSXineramadataPtr[stuff->screen].width; + rep.height = SiSXineramadataPtr[stuff->screen].height; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + +int +SiSProcXineramaIsActive(ClientPtr client) +{ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !SiSnoPanoramiXExtension; + if(client->swapped) { + register int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.state, n); + } + WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep); + return client->noClientException; +} + +int +SiSProcXineramaQueryScreens(ClientPtr client) +{ + xXineramaQueryScreensReply rep; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = (SiSnoPanoramiXExtension) ? 0 : SiSXineramaNumScreens; + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + if(client->swapped) { + register int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.number, n); + } + WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep); + + if(!SiSnoPanoramiXExtension) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < SiSXineramaNumScreens; i++) { + scratch.x_org = SiSXineramadataPtr[i].x; + scratch.y_org = SiSXineramadataPtr[i].y; + scratch.width = SiSXineramadataPtr[i].width; + scratch.height = SiSXineramadataPtr[i].height; + if(client->swapped) { + register int n; + swaps(&scratch.x_org, n); + swaps(&scratch.y_org, n); + swaps(&scratch.width, n); + swaps(&scratch.height, n); + } + WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch); + } + } + + return client->noClientException; +} + +static int +SiSProcXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return SiSProcXineramaQueryVersion(client); + case X_PanoramiXGetState: + return SiSProcXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return SiSProcXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SiSProcXineramaGetScreenSize(client); + case X_XineramaIsActive: + return SiSProcXineramaIsActive(client); + case X_XineramaQueryScreens: + return SiSProcXineramaQueryScreens(client); + } + return BadRequest; +} + +/* SProc */ + +static int +SiSSProcXineramaQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return SiSProcXineramaQueryVersion(client); +} + +static int +SiSSProcXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + return SiSProcXineramaGetState(client); +} + +static int +SiSSProcXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + return SiSProcXineramaGetScreenCount(client); +} + +static int +SiSSProcXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + return SiSProcXineramaGetScreenSize(client); +} + +static int +SiSSProcXineramaIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return SiSProcXineramaIsActive(client); +} + +static int +SiSSProcXineramaQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return SiSProcXineramaQueryScreens(client); +} + +int +SiSSProcXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return SiSSProcXineramaQueryVersion(client); + case X_PanoramiXGetState: + return SiSSProcXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return SiSSProcXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SiSSProcXineramaGetScreenSize(client); + case X_XineramaIsActive: + return SiSSProcXineramaIsActive(client); + case X_XineramaQueryScreens: + return SiSSProcXineramaQueryScreens(client); + } + return BadRequest; +} + +static void +SiSXineramaResetProc(ExtensionEntry* extEntry) +{ + /* Called by CloseDownExtensions() */ + if(SiSXineramadataPtr) { + Xfree(SiSXineramadataPtr); + SiSXineramadataPtr = NULL; + } +} + +static void +SiSXineramaExtensionInit(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + Bool success = FALSE; + + if(!(SiSXineramadataPtr)) { + + if(!pSiS->MergedFB) { + SiSnoPanoramiXExtension = TRUE; + return; + } + + if(!noPanoramiXExtension) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Xinerama active, not initializing SiS Pseudo-Xinerama\n"); + SiSnoPanoramiXExtension = TRUE; + return; + } + + if(SiSnoPanoramiXExtension) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiS Pseudo-Xinerama disabled\n"); + return; + } + + if(pSiS->CRT2Position == sisClone) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Running MergedFB in Clone mode, SiS Pseudo-Xinerama disabled\n"); + SiSnoPanoramiXExtension = TRUE; + return; + } + + if(!(pSiS->AtLeastOneNonClone)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Only Clone modes defined, SiS Pseudo-Xinerama disabled\n"); + SiSnoPanoramiXExtension = TRUE; + return; + } + + SiSXineramaNumScreens = 2; + + while(SiSXineramaGeneration != serverGeneration) { + + pSiS->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + SiSProcXineramaDispatch, + SiSSProcXineramaDispatch, + SiSXineramaResetProc, + StandardMinorOpcode); + + if(!pSiS->XineramaExtEntry) break; + + SiSXineramaReqCode = (unsigned char)pSiS->XineramaExtEntry->base; + + if(!(SiSXineramadataPtr = (SiSXineramaData *) + xcalloc(SiSXineramaNumScreens, sizeof(SiSXineramaData)))) break; + + SiSXineramaGeneration = serverGeneration; + success = TRUE; + } + + if(!success) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize SiS Pseudo-Xinerama extension\n"); + SiSnoPanoramiXExtension = TRUE; + return; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Initialized SiS Pseudo-Xinerama extension\n"); + + pSiS->SiSXineramaVX = 0; + pSiS->SiSXineramaVY = 0; + + } + + SiSUpdateXineramaScreenInfo(pScrn); + +} +#endif /* End of PseudoXinerama */ + +#endif /* End of MergedFB helpers */ + static xf86MonPtr SiSInternalDDC(ScrnInfoPtr pScrn, int crtno) { SISPtr pSiS = SISPTR(pScrn); - USHORT temp, i; + USHORT temp, i, realcrtno = crtno; unsigned char buffer[256]; xf86MonPtr pMonitor = NULL; - /* TW: If CRT1 is off, skip DDC */ + /* If CRT1 is off, skip DDC */ if((pSiS->CRT1off) && (!crtno)) return NULL; - temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 0, &buffer[0]); + if(crtno) { + if(pSiS->VBFlags & CRT2_LCD) realcrtno = 1; + else if(pSiS->VBFlags & CRT2_VGA) realcrtno = 2; + else return NULL; + } + + temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, realcrtno, 0, &buffer[0]); if((!temp) || (temp == 0xffff)) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "CRT%d DDC probing failed, now trying via VBE\n", crtno + 1); + "CRT%d DDC probing failed%s\n", crtno + 1, + (crtno == 0) ? ", now trying via VBE" : ""); return(NULL); } else { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT%d DDC supported\n", crtno + 1); @@ -1085,12 +1961,12 @@ SiSInternalDDC(ScrnInfoPtr pScrn, int crtno) crtno + 1, (temp & 0x1a) ? "" : "[none of the supported]", (temp & 0x02) ? "2 " : "", - (temp & 0x08) ? "3 " : "", - (temp & 0x10) ? "4" : ""); + (temp & 0x08) ? "D&P" : "", + (temp & 0x10) ? "FPDI-2" : ""); if(temp & 0x02) { i = 3; /* Number of retrys */ do { - temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 1, &buffer[0]); + temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, realcrtno, 1, &buffer[0]); } while((temp) && i--); if(!temp) { if((pMonitor = xf86InterpretEDID(pScrn->scrnIndex, &buffer[0]))) { @@ -1105,11 +1981,16 @@ SiSInternalDDC(ScrnInfoPtr pScrn, int crtno) "CRT%d DDC reading failed\n", crtno + 1); return(NULL); } - } else { + } else if(!crtno) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "DDC levels 3 and 4 not supported by this driver yet.\n"); + "DDC for VESA D&P and FPDI-2 not supported for CRT1.\n"); return(NULL); - } + } else if(temp & 0x18) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "DDC for VESA D&P and FPDI-2 not supported for CRT2 yet.\n"); + return(NULL); + } + return(NULL); } } @@ -1119,11 +2000,56 @@ SiSDoPrivateDDC(ScrnInfoPtr pScrn) SISPtr pSiS = SISPTR(pScrn); #ifdef SISDUALHEAD - if((pSiS->DualHeadMode) && (!pSiS->SecondHead)) - return(SiSInternalDDC(pScrn, 1)); - else + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) + return(SiSInternalDDC(pScrn, 0)); + else + return(SiSInternalDDC(pScrn, 1)); + } else #endif - return(SiSInternalDDC(pScrn, 0)); + if(pSiS->CRT1off) + return(SiSInternalDDC(pScrn, 1)); + else + return(SiSInternalDDC(pScrn, 0)); +} + +static BOOLEAN +SiSMakeOwnModeList(ScrnInfoPtr pScrn, BOOLEAN acceptcustommodes, BOOLEAN includelcdmodes, + BOOLEAN isfordvi, BOOLEAN *havecustommodes) +{ + DisplayModePtr tempmode, delmode, mymodes; + + if((mymodes = SiSBuildBuiltInModeList(pScrn, includelcdmodes, isfordvi))) { + if(!acceptcustommodes) { + while(pScrn->monitor->Modes) + xf86DeleteMode(&pScrn->monitor->Modes, pScrn->monitor->Modes); + pScrn->monitor->Modes = mymodes; + } else { + delmode = pScrn->monitor->Modes; + while(delmode) { + if(delmode->type & M_T_DEFAULT) { + tempmode = delmode->next; + xf86DeleteMode(&pScrn->monitor->Modes, delmode); + delmode = tempmode; + } else { + delmode = delmode->next; + } + } + tempmode = pScrn->monitor->Modes; + if(tempmode) *havecustommodes = TRUE; + pScrn->monitor->Modes = mymodes; + while(mymodes) { + if(!mymodes->next) break; + else mymodes = mymodes->next; + } + mymodes->next = tempmode; + if(tempmode) { + tempmode->prev = mymodes; + } + } + return TRUE; + } else + return FALSE; } /* Mandatory */ @@ -1133,7 +2059,8 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) SISPtr pSiS; MessageType from; unsigned char usScratchCR17, CR5F; - unsigned char usScratchCR32; + unsigned char usScratchCR32, usScratchCR63; + unsigned char usScratchSR1F; unsigned long int i; int temp; ClockRangePtr clockRanges; @@ -1144,7 +2071,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) SISEntPtr pSiSEnt = NULL; #endif DisplayModePtr first, p, n; - DisplayModePtr tempmode, delmode, mymodes; unsigned char srlockReg,crlockReg; unsigned char tempreg; xf86MonPtr pMonitor = NULL; @@ -1153,20 +2079,20 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) vbeInfoPtr pVbe; VbeInfoBlock *vbe; - if (flags & PROBE_DETECT) { - if (xf86LoadSubModule(pScrn, "vbe")) { - int index = xf86GetEntityInfo(pScrn->entityList[0])->index; - + if(flags & PROBE_DETECT) { + if(xf86LoadSubModule(pScrn, "vbe")) { + int index = xf86GetEntityInfo(pScrn->entityList[0])->index; + #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) - if((pVbe = VBEInit(NULL,index))) { + if((pVbe = VBEInit(NULL,index))) { #else - if((pVbe = VBEExtendedInit(NULL,index,0))) { + if((pVbe = VBEExtendedInit(NULL,index,0))) { #endif - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); - } - } - return TRUE; + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } + } + return TRUE; } /* @@ -1191,32 +2117,34 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* The vgahw module should be loaded here when needed */ if(!xf86LoadSubModule(pScrn, "vgahw")) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not load vgahw module\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load vgahw module\n"); + return FALSE; } xf86LoaderReqSymLists(vgahwSymbols, NULL); xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SiS driver (31/01/03-1) by " - "Thomas Winischhofer <thomas@winischhofer.net>\n"); + "SiS driver (%d/%02d/%02d-%d) by " + "Thomas Winischhofer <thomas@winischhofer.net>\n", + SISDRIVERVERSIONYEAR + 2000, SISDRIVERVERSIONMONTH, + SISDRIVERVERSIONDAY, SISDRIVERREVISION); xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "See http://www.winischhofer.net/linuxsisvga.shtml " - "for documentation and updates\n"); + "See http://www.winischhofer.net/linuxsisvga.shtml " + "for documentation and updates\n"); /* Allocate a vgaHWRec */ if(!vgaHWGetHWRec(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate VGA private\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate VGA private\n"); + return FALSE; } /* Allocate the SISRec driverPrivate */ if(!SISGetRec(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate memory for pSiS private\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate memory for pSiS private\n"); + return FALSE; } pSiS = SISPTR(pScrn); pSiS->pScrn = pScrn; @@ -1230,26 +2158,26 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* Get the entity, and make sure it is PCI. */ pSiS->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if(pSiS->pEnt->location.type != BUS_PCI) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Entity's bus type is not PCI\n"); - SISFreeRec(pScrn); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Entity's bus type is not PCI\n"); + SISFreeRec(pScrn); + return FALSE; } #ifdef SISDUALHEAD - /* TW: Allocate an entity private if necessary */ + /* Allocate an entity private if necessary */ if(xf86IsEntityShared(pScrn->entityList[0])) { - pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0], + pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0], SISEntityIndex)->ptr; - pSiS->entityPrivate = pSiSEnt; - - /* TW: If something went wrong, quit here */ - if ((pSiSEnt->DisableDual) || (pSiSEnt->ErrorAfterFirst)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "First head encountered fatal error, can't continue\n"); - SISFreeRec(pScrn); - return FALSE; - } + pSiS->entityPrivate = pSiSEnt; + + /* If something went wrong, quit here */ + if((pSiSEnt->DisableDual) || (pSiSEnt->ErrorAfterFirst)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "First head encountered fatal error, can't continue\n"); + SISFreeRec(pScrn); + return FALSE; + } } #endif @@ -1274,8 +2202,8 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } vgaHWGetIOBase(VGAHWPTR(pScrn)); - /* TW: We "patch" the PIOOffset inside vgaHW in order to force - * the vgaHW module to use our relocated i/o ports. + /* We "patch" the PIOOffset inside vgaHW in order to force + * the vgaHW module to use our relocated i/o ports. */ VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; @@ -1315,14 +2243,14 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* The ramdac module should be loaded here when needed */ if(!xf86LoadSubModule(pScrn, "ramdac")) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not load ramdac module\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load ramdac module\n"); #ifdef SISDUALHEAD - if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; #endif - if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); - SISFreeRec(pScrn); - return FALSE; + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); + return FALSE; } xf86LoaderReqSymLists(ramdacSymbols, NULL); @@ -1334,32 +2262,32 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) * Set the Chipset and ChipRev, allowing config file entries to * override. DANGEROUS! */ - if (pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) { - pScrn->chipset = pSiS->pEnt->device->chipset; - pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset); - from = X_CONFIG; - } else if (pSiS->pEnt->device->chipID >= 0) { - pSiS->Chipset = pSiS->pEnt->device->chipID; - pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset); - - from = X_CONFIG; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + if(pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) { + pScrn->chipset = pSiS->pEnt->device->chipset; + pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset); + from = X_CONFIG; + } else if(pSiS->pEnt->device->chipID >= 0) { + pSiS->Chipset = pSiS->pEnt->device->chipID; + pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset); + + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", pSiS->Chipset); } else { - from = X_PROBED; - pSiS->Chipset = pSiS->PciInfo->chipType; - pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset); + from = X_PROBED; + pSiS->Chipset = pSiS->PciInfo->chipType; + pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset); } - if (pSiS->pEnt->device->chipRev >= 0) { - pSiS->ChipRev = pSiS->pEnt->device->chipRev; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + if(pSiS->pEnt->device->chipRev >= 0) { + pSiS->ChipRev = pSiS->pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", pSiS->ChipRev); } else { - pSiS->ChipRev = pSiS->PciInfo->chipRev; + pSiS->ChipRev = pSiS->PciInfo->chipRev; } pSiS->sishw_ext.jChipRevision = pSiS->ChipRev; - /* TW: Determine SiS6326 chiprevision. This is not yet used for + /* Determine SiS6326 chiprevision. This is not yet used for * anything, but it will as soon as I found out on which revisions * the hardware video overlay really works. * According to SiS the only differences are: @@ -1370,19 +2298,19 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) */ pSiS->SiS6326Flags = 0; if(pSiS->Chipset == PCI_CHIP_SIS6326) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chipset is SiS6326 %s (revision 0x%02x)\n", (pSiS->ChipRev == 0xaf) ? "(Ax)" : ((pSiS->ChipRev == 0x0a) ? "AGP (G0)" : ((pSiS->ChipRev == 0x0b) ? "AGP (H0)" : - (((pSiS->ChipRev & 0xf0) == 0xd0) ? "DVD (Dx)" : + (((pSiS->ChipRev & 0xf0) == 0xd0) ? "DVD (Dx/H0)" : (((pSiS->ChipRev & 0xf0) == 0x90) ? "(9x)" : (((pSiS->ChipRev & 0xf0) == 0xc0) ? "(Cx)" : "(unknown)"))))), pSiS->ChipRev); - if((pSiS->ChipRev != 0x0a) && (pSiS->ChipRev != 0x0b)) { + if((pSiS->ChipRev != 0x0a) && (pSiS->ChipRev != 0x0b)) { pSiS->SiS6326Flags |= SIS6326_HASTV; - } + } } @@ -1390,32 +2318,35 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) * This shouldn't happen because such problems should be caught in * SISProbe(), but check it just in case. */ - if (pScrn->chipset == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + if(pScrn->chipset == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04X is not recognised\n", pSiS->Chipset); #ifdef SISDUALHEAD - if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; #endif - if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); - SISFreeRec(pScrn); - return FALSE; + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); + return FALSE; } - if (pSiS->Chipset < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + if(pSiS->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Chipset \"%s\" is not recognised\n", pScrn->chipset); #ifdef SISDUALHEAD - if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; #endif - if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); - SISFreeRec(pScrn); - return FALSE; + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); + return FALSE; } - /* TW: Determine chipset and VGA engine type for new mode switching code */ + /* Determine chipset and VGA engine type for new mode switching code */ + pSiS->ChipFlags = 0; + pSiS->SiS_SD_Flags = 0; switch(pSiS->Chipset) { case PCI_CHIP_SIS300: pSiS->sishw_ext.jChipType = SIS_300; pSiS->VGAEngine = SIS_300_VGA; + pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES; break; case PCI_CHIP_SIS630: /* 630 + 730 */ pSiS->sishw_ext.jChipType = SIS_630; @@ -1423,23 +2354,27 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->sishw_ext.jChipType = SIS_730; } pSiS->VGAEngine = SIS_300_VGA; + pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES; break; case PCI_CHIP_SIS540: pSiS->sishw_ext.jChipType = SIS_540; pSiS->VGAEngine = SIS_300_VGA; + pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES; break; case PCI_CHIP_SIS315H: pSiS->sishw_ext.jChipType = SIS_315H; pSiS->VGAEngine = SIS_315_VGA; + pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES; break; case PCI_CHIP_SIS315: - /* TW: Override for simplicity */ + /* Override for simplicity */ pSiS->Chipset = PCI_CHIP_SIS315H; pSiS->sishw_ext.jChipType = SIS_315; pSiS->VGAEngine = SIS_315_VGA; + pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES; break; case PCI_CHIP_SIS315PRO: - /* TW: Override for simplicity */ + /* Override for simplicity */ pSiS->Chipset = PCI_CHIP_SIS315H; pSiS->sishw_ext.jChipType = SIS_315PRO; pSiS->VGAEngine = SIS_315_VGA; @@ -1447,14 +2382,32 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) case PCI_CHIP_SIS550: pSiS->sishw_ext.jChipType = SIS_550; pSiS->VGAEngine = SIS_315_VGA; + pSiS->ChipFlags |= SiSCF_Integrated; + pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES; break; case PCI_CHIP_SIS650: /* 650 + 740 */ pSiS->sishw_ext.jChipType = SIS_650; + if(pciReadLong(0x00000000, 0x00) == 0x07401039) { + pSiS->sishw_ext.jChipType = SIS_740; + } pSiS->VGAEngine = SIS_315_VGA; + pSiS->ChipFlags |= SiSCF_Integrated; + pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES; break; case PCI_CHIP_SIS330: pSiS->sishw_ext.jChipType = SIS_330; - pSiS->VGAEngine = SIS_315_VGA; + pSiS->VGAEngine = SIS_315_VGA; + pSiS->ChipFlags |= SiSCF_XabreCore; + pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES; + break; + case PCI_CHIP_SIS660: /* 660 + 760 */ + pSiS->sishw_ext.jChipType = SIS_660; + if(pciReadLong(0x00000000, 0x00) == 0x07601039) { + pSiS->sishw_ext.jChipType = SIS_760; + } + pSiS->VGAEngine = SIS_315_VGA; + pSiS->ChipFlags |= (SiSCF_XabreCore | SiSCF_Integrated); + pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES; break; case PCI_CHIP_SIS530: pSiS->sishw_ext.jChipType = SIS_530; @@ -1466,17 +2419,24 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) break; } - /* TW: Now check if sisfb is loaded. Since sisfb only supports - * the 300 and 310/325 series, we only do this for these chips. + /* Now check if sisfb is loaded. Since sisfb only supports + * the 300 and 315 series, we only do this for these chips. * We use this for checking where sisfb starts its memory * heap in order to automatically detect the correct MaxXFBMem * setting (which normally is given by the option of the same name). - * That only works if sisfb is completely running, ie with - * a video mode (because the fbdev will not be installed otherwise.) + * Under kernel 2.4.y, that only works if sisfb is completely + * running, ie with a video mode because the fbdev will not be + * installed otherwise. Under 2.5 and later, sisfb will install + * the framebuffer device in any way and running it with mode=none + * is no longer supported (or necessary). */ pSiS->donttrustpdc = FALSE; pSiS->sisfbpdc = 0; + pSiS->sisfblcda = 0xff; + pSiS->sisfbscalelcd = -1; + pSiS->sisfbspecialtiming = CUT_NONE; + pSiS->OldMode = 0; if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { @@ -1484,86 +2444,97 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) sisfb_info mysisfbinfo; BOOL found = FALSE; char name[10]; + CARD32 sisfbversion; - i=0; - do { - sprintf(name, "/dev/fb%1d", i); - if((fd = open(name, 'r'))) { + { + i=0; + do { + sprintf(name, "/dev/fb%1d", i); + if((fd = open(name, 'r')) != -1) { + + if(!ioctl(fd, SISFB_GET_INFO, &mysisfbinfo)) { - if(!ioctl(fd, SISFB_GET_INFO, &mysisfbinfo)) { + if(mysisfbinfo.sisfb_id == SISFB_ID) { - if(mysisfbinfo.sisfb_id == SISFB_ID) { + sisfbversion = (mysisfbinfo.sisfb_version << 16) | + (mysisfbinfo.sisfb_revision << 8) | + (mysisfbinfo.sisfb_patchlevel); - if((mysisfbinfo.sisfb_version >= 1) && - (mysisfbinfo.sisfb_revision >=5) && - (mysisfbinfo.sisfb_patchlevel >= 8)) { - /* TW: Added PCI bus/slot/func into in sisfb Version 1.5.08. + if(sisfbversion >= 0x010508) { + /* Added PCI bus/slot/func into in sisfb Version 1.5.08. Check this to make sure we run on the same card as sisfb - */ - if((mysisfbinfo.sisfb_pcibus == pSiS->PciInfo->bus) && - (mysisfbinfo.sisfb_pcislot == pSiS->PciInfo->device) && - (mysisfbinfo.sisfb_pcifunc == pSiS->PciInfo->func) ) { - found = TRUE; - } - } else found = TRUE; - - if(found) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "%s: SiS kernel fb driver (sisfb) %d.%d.%d detected (PCI: %02d:%02d.%d)\n", - &name[5], - mysisfbinfo.sisfb_version, - mysisfbinfo.sisfb_revision, - mysisfbinfo.sisfb_patchlevel, - pSiS->PciInfo->bus, - pSiS->PciInfo->device, - pSiS->PciInfo->func); - /* TW: Added version/rev/pl in sisfb 1.4.0 */ - if(mysisfbinfo.sisfb_version == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Old version of sisfb found. Please update\n"); - } - pSiS->sisfbMem = mysisfbinfo.heapstart; - /* TW: Basically, we can't trust the pdc register if sisfb is loaded */ - pSiS->donttrustpdc = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "sisfb: memory heap starts at %dKB\n", pSiS->sisfbMem); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "sisfb: using video mode 0x%02x\n", mysisfbinfo.fbvidmode); - if((mysisfbinfo.sisfb_version >= 1) && - (mysisfbinfo.sisfb_revision >=5) && - (mysisfbinfo.sisfb_patchlevel >= 6)) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "sisfb: %sreserved hardware cursor, using %s command queue\n", - (mysisfbinfo.sisfb_caps & 0x80) ? "" : "not ", - (mysisfbinfo.sisfb_caps & 0x40) ? "SiS300 series Turbo" : - (mysisfbinfo.sisfb_caps & 0x20) ? "SiS310/325 series AGP" : - (mysisfbinfo.sisfb_caps & 0x10) ? "SiS310/325 series VRAM" : - (mysisfbinfo.sisfb_caps & 0x08) ? "SiS310/325 series MMIO" : - "no"); - } - if((mysisfbinfo.sisfb_version >= 1) && - (mysisfbinfo.sisfb_revision >=5) && - (mysisfbinfo.sisfb_patchlevel >= 10)) { - /* TW: We can trust the pdc value if sisfb is of recent version */ - pSiS->donttrustpdc = FALSE; - if(mysisfbinfo.sisfb_patchlevel >= 11) { - pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc; + */ + if((mysisfbinfo.sisfb_pcibus == pSiS->PciInfo->bus) && + (mysisfbinfo.sisfb_pcislot == pSiS->PciInfo->device) && + (mysisfbinfo.sisfb_pcifunc == pSiS->PciInfo->func) ) { + found = TRUE; + } + } else found = TRUE; + + if(found) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "%s: SiS kernel fb driver (sisfb) %d.%d.%d detected (PCI: %02d:%02d.%d)\n", + &name[5], + mysisfbinfo.sisfb_version, + mysisfbinfo.sisfb_revision, + mysisfbinfo.sisfb_patchlevel, + pSiS->PciInfo->bus, + pSiS->PciInfo->device, + pSiS->PciInfo->func); + /* Added version/rev/pl in sisfb 1.4.0 */ + if(mysisfbinfo.sisfb_version == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Old version of sisfb found. Please update\n"); + } + pSiS->sisfbMem = mysisfbinfo.heapstart; + /* Basically, we can't trust the pdc register if sisfb is loaded */ + pSiS->donttrustpdc = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: memory heap starts at %dKB\n", pSiS->sisfbMem); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: using video mode 0x%02x\n", mysisfbinfo.fbvidmode); + pSiS->OldMode = mysisfbinfo.fbvidmode; + if(sisfbversion >= 0x010506) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: %sreserved hardware cursor, using %s command queue\n", + (mysisfbinfo.sisfb_caps & 0x80) ? "" : "not ", + (mysisfbinfo.sisfb_caps & 0x40) ? "SiS300 series Turbo" : + (mysisfbinfo.sisfb_caps & 0x20) ? "SiS315 series AGP" : + (mysisfbinfo.sisfb_caps & 0x10) ? "SiS315 series VRAM" : + (mysisfbinfo.sisfb_caps & 0x08) ? "SiS315 series MMIO" : + "no"); + } + if(sisfbversion >= 0x01050A) { + /* We can trust the pdc value if sisfb is of recent version */ + pSiS->donttrustpdc = FALSE; + if(sisfbversion >= 0x01050B) { + /* As of 1.5.11, sisfb saved the register for us */ + pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc; + } + if(sisfbversion >= 0x01050E) { + if(pSiS->VGAEngine == SIS_315_VGA) { + pSiS->sisfblcda = mysisfbinfo.sisfb_lcda; + } + if(sisfbversion >= 0x01060D) { + pSiS->sisfbscalelcd = mysisfbinfo.sisfb_scalelcd; + pSiS->sisfbspecialtiming = mysisfbinfo.sisfb_specialtiming; + } + } + } } - } - } - } - } - close (fd); - } - i++; - - } while((i <= 7) && (!found)); + } + } + close (fd); + } + i++; + } while((i <= 7) && (!found)); + if(!found) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "sisfb not found\n"); + } } /* * The first thing we should figure out is the depth, bpp, etc. - * TW: Additionally, determine the size of the HWCursor memory - * area. + * Additionally, determine the size of the HWCursor memory area. */ switch (pSiS->VGAEngine) { case SIS_300_VGA: @@ -1592,11 +2563,11 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } #ifdef SISDUALHEAD - /* TW: In case of Dual Head, we need to determine if we are the "master" head or - * the "slave" head. In order to do that, we set PrimInit to DONE in the - * shared entity at the end of the first initialization. The second - * initialization then knows that some things have already been done. THIS - * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER! + /* In case of Dual Head, we need to determine if we are the "master" head or + * the "slave" head. In order to do that, we set PrimInit to DONE in the + * shared entity at the end of the first initialization. The second + * initialization then knows that some things have already been done. THIS + * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER! */ if(xf86IsEntityShared(pScrn->entityList[0])) { @@ -1617,13 +2588,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->DualHeadMode = TRUE; } } else { - /* TW: Only one screen in config file - disable dual head mode */ + /* Only one screen in config file - disable dual head mode */ pSiS->SecondHead = FALSE; pSiS->DualHeadMode = FALSE; pSiSEnt->DisableDual = TRUE; } } else { - /* TW: Entity is not shared - disable dual head mode */ + /* Entity is not shared - disable dual head mode */ pSiS->SecondHead = FALSE; pSiS->DualHeadMode = FALSE; } @@ -1631,7 +2602,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->ForceCursorOff = FALSE; - /* TW: Allocate SiS_Private (for mode switching code) and initialize it */ + /* Allocate SiS_Private (for mode switching code) and initialize it */ pSiS->SiS_Pr = NULL; #ifdef SISDUALHEAD if(pSiSEnt) { @@ -1653,30 +2624,37 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(pSiSEnt) pSiSEnt->SiS_Pr = pSiS->SiS_Pr; #endif memset(pSiS->SiS_Pr, 0, sizeof(SiS_Private)); + pSiS->SiS_Pr->SiS_Backup70xx = 0xff; + pSiS->SiS_Pr->SiS_CHOverScan = -1; + pSiS->SiS_Pr->SiS_ChSW = FALSE; + pSiS->SiS_Pr->SiS_CustomT = CUT_NONE; + pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE; } - pSiS->SiS_Pr->SiS_Backup70xx = 0xff; - pSiS->SiS_Pr->SiS_CHOverScan = -1; - pSiS->SiS_Pr->SiS_ChSW = FALSE; - pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE; - /* TW: Get our relocated IO registers */ + /* Get our relocated IO registers */ pSiS->RelIO = (pSiS->PciInfo->ioBase[2] & 0xFFFC) + pSiS->IODBase; pSiS->sishw_ext.ulIOAddress = pSiS->RelIO + 0x30; xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n", (unsigned long)pSiS->RelIO); - /* TW: Initialize SiS Port Reg definitions for externally used - * BIOS emulation (init.c/init301.c) functions. + /* Initialize SiS Port Reg definitions for externally used + * BIOS emulation (init.c/init301.c) functions. */ SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO + 0x30); - /* TW: The following identifies the old chipsets. This is only - * partly used since the really old chips are not supported, - * but I keep it here for future use. + /* The following identifies the old chipsets. This is only + * partly used since the really old chips are not supported, + * but I keep it here for future use. + * 205, 215 and 225 are to be treated the same way, 201 and 202 + * are different. */ if(pSiS->VGAEngine == SIS_OLD_VGA || pSiS->VGAEngine == SIS_530_VGA) { switch(pSiS->Chipset) { - case PCI_CHIP_SG86C205: /* Just for making it complete */ + case PCI_CHIP_SG86C201: + pSiS->oldChipset = OC_SIS86201; break; + case PCI_CHIP_SG86C202: + pSiS->oldChipset = OC_SIS86202; break; + case PCI_CHIP_SG86C205: { unsigned char temp; sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg); @@ -1686,18 +2664,22 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) OC_SIS6205C : OC_SIS6205A; break; } - case PCI_CHIP_SIS82C204: /* Just for making it complete */ + case PCI_CHIP_SIS82C204: pSiS->oldChipset = OC_SIS82204; break; - case 0x6225: /* Just for making it complete */ + case 0x6225: pSiS->oldChipset = OC_SIS6225; break; case PCI_CHIP_SIS5597: pSiS->oldChipset = OC_SIS5597; break; case PCI_CHIP_SIS6326: pSiS->oldChipset = OC_SIS6326; break; case PCI_CHIP_SIS530: - if((pSiS->ChipRev & 0x0f) < 0x0a) - pSiS->oldChipset = OC_SIS530A; - else pSiS->oldChipset = OC_SIS530B; + if(pciReadLong(0x00000000, 0x00) == 0x06201039) { + pSiS->oldChipset = OC_SIS620; + } else { + if((pSiS->ChipRev & 0x0f) < 0x0a) + pSiS->oldChipset = OC_SIS530A; + else pSiS->oldChipset = OC_SIS530B; + } break; default: pSiS->oldChipset = OC_UNKNOWN; @@ -1721,7 +2703,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) case 8: case 16: case 24: - break; + break; case 15: if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) @@ -1797,7 +2779,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } } - /* TW: Set the current layout parameters */ + /* Set the current layout parameters */ pSiS->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; pSiS->CurrentLayout.depth = pScrn->depth; /* (Inside this function, we can use pScrn's contents anyway) */ @@ -1826,6 +2808,28 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } } +#ifdef SISDUALHEAD + /* Due to palette & timing problems we don't support 8bpp in DHM */ + if((pSiS->DualHeadMode) && (pScrn->bitsPerPixel == 8)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Color depth 8 not supported in Dual Head mode.\n"); + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); + return FALSE; + } +#endif +#ifdef SISMERGED + /* Due to palette & timing problems we don't support 8bpp in MFBM */ + if((pSiS->MergedFB) && (pScrn->bitsPerPixel == 8)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Color depth 8 not supported in MergedFB mode.\n"); + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); + return FALSE; + } +#endif + /* * The cmap layer needs this to be initialised. */ @@ -1859,11 +2863,11 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* Unlock registers */ sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg); - /* TW: We need no backup area (300/310/325 new mode switching code) */ + /* We need no backup area (300/315/330 new mode switching code) */ pSiS->sishw_ext.pSR = NULL; pSiS->sishw_ext.pCR = NULL; - /* TW: Read BIOS for 300 and 310/325 series customization */ + /* Read BIOS for 300 and 315/330 series customization */ pSiS->sishw_ext.pjVirtualRomBase = NULL; pSiS->BIOS = NULL; pSiS->sishw_ext.UseROM = FALSE; @@ -1887,15 +2891,15 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) BOOLEAN found; int i; static const char sis_rom_sig[] = "Silicon Integrated Systems"; - static const char *sis_sig[10] = { + static const char *sis_sig[13] = { "300", "540", "630", "730", - "315", "315", "315", "5315", "6325", - "Xabre" + "315", "315", "315", "5315", "6325", "6325", + "Xabre", "6330", "6330" /* 6330 is a guess */ }; - static const unsigned short sis_nums[10] = { + static const unsigned short sis_nums[13] = { SIS_300, SIS_540, SIS_630, SIS_730, - SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, - SIS_330 + SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, + SIS_330, SIS_660, SIS_760 }; found = FALSE; @@ -1915,14 +2919,16 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) romptr = pSiS->BIOS[0x14] | (pSiS->BIOS[0x15] << 8); if(romptr > (BIOS_SIZE - 5)) continue; - for(i = 0; (i < 10) && (!found); i++) { + for(i = 0; (i < 13) && (!found); i++) { if(strncmp(sis_sig[i], (char *)&pSiS->BIOS[romptr], strlen(sis_sig[i])) == 0) { if(sis_nums[i] == pSiS->sishw_ext.jChipType) { found = TRUE; break; } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + if((pSiS->sishw_ext.jChipType != SIS_740) && (pSiS->sishw_ext.jChipType != SIS_760)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Ignoring BIOS for SiS %s at %p\n", sis_sig[i], segstart); + } } } } @@ -1957,22 +2963,23 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { if(!pSiS->SecondHead) { - /* TW: Copy some option settings to entity private */ + /* Copy some option settings to entity private */ pSiSEnt->HWCursor = pSiS->HWCursor; + pSiSEnt->NoAccel = pSiS->NoAccel; + pSiSEnt->restorebyset = pSiS->restorebyset; + pSiSEnt->OptROMUsage = pSiS->OptROMUsage; + pSiSEnt->OptUseOEM = pSiS->OptUseOEM; + pSiSEnt->TurboQueue = pSiS->TurboQueue; + pSiSEnt->forceCRT1 = pSiS->forceCRT1; pSiSEnt->ForceCRT2Type = pSiS->ForceCRT2Type; pSiSEnt->ForceTVType = pSiS->ForceTVType; - pSiSEnt->TurboQueue = pSiS->TurboQueue; + pSiSEnt->UsePanelScaler = pSiS->UsePanelScaler; pSiSEnt->PDC = pSiS->PDC; + pSiSEnt->DSTN = pSiS->DSTN; pSiSEnt->OptTVStand = pSiS->OptTVStand; pSiSEnt->NonDefaultPAL = pSiS->NonDefaultPAL; pSiSEnt->OptTVOver = pSiS->OptTVOver; pSiSEnt->OptTVSOver = pSiS->OptTVSOver; - pSiSEnt->OptROMUsage = pSiS->OptROMUsage; - pSiSEnt->DSTN = pSiS->DSTN; - pSiSEnt->XvOnCRT2 = pSiS->XvOnCRT2; - pSiSEnt->NoAccel = pSiS->NoAccel; - pSiSEnt->NoXvideo = pSiS->NoXvideo; - pSiSEnt->forceCRT1 = pSiS->forceCRT1; pSiSEnt->chtvlumabandwidthcvbs = pSiS->chtvlumabandwidthcvbs; pSiSEnt->chtvlumabandwidthsvideo = pSiS->chtvlumabandwidthsvideo; pSiSEnt->chtvlumaflickerfilter = pSiS->chtvlumaflickerfilter; @@ -1984,9 +2991,22 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiSEnt->sistvedgeenhance = pSiS->sistvedgeenhance; pSiSEnt->sistvantiflicker = pSiS->sistvantiflicker; pSiSEnt->sistvsaturation = pSiS->sistvsaturation; + pSiSEnt->sistvcfilter = pSiS->sistvcfilter; + pSiSEnt->sistvyfilter = pSiS->sistvyfilter; + pSiSEnt->sistvcolcalibc = pSiS->sistvcolcalibc; + pSiSEnt->sistvcolcalibf = pSiS->sistvcolcalibf; pSiSEnt->tvxpos = pSiS->tvxpos; pSiSEnt->tvypos = pSiS->tvypos; - pSiSEnt->restorebyset = pSiS->restorebyset; + pSiSEnt->tvxscale = pSiS->tvxscale; + pSiSEnt->tvyscale = pSiS->tvyscale; + pSiSEnt->CRT1gamma = pSiS->CRT1gamma; + pSiSEnt->CRT2gamma = pSiS->CRT2gamma; + pSiSEnt->XvOnCRT2 = pSiS->XvOnCRT2; + pSiSEnt->AllowHotkey = pSiS->AllowHotkey; + pSiSEnt->enablesisctrl = pSiS->enablesisctrl; +#ifdef SIS_CP + SIS_CP_DRIVER_COPYOPTIONSENT +#endif } else { /* We always use same cursor type on both screens */ if(pSiS->HWCursor != pSiSEnt->HWCursor) { @@ -1997,85 +3017,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) "Master head ruled: HWCursor shall be %s\n", pSiS->HWCursor ? "enabled" : "disabled"); } - /* We need to use identical CRT2 Type setting */ - if(pSiS->ForceCRT2Type != pSiSEnt->ForceCRT2Type) { - if(pSiS->ForceCRT2Type != CRT2_DEFAULT) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Ignoring inconsistent ForceCRT2Type setting. Master head rules\n"); - } - pSiS->ForceCRT2Type = pSiSEnt->ForceCRT2Type; - } - if(pSiS->ForceTVType != pSiSEnt->ForceTVType) { - if(pSiS->ForceTVType != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Ignoring inconsistent ForceTVType setting. Master head rules\n"); - } - pSiS->ForceTVType = pSiSEnt->ForceTVType; - } - /* We need identical TurboQueue setting */ - if(pSiS->TurboQueue != pSiSEnt->TurboQueue) { - pSiS->TurboQueue = pSiSEnt->TurboQueue; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent TurboQueue setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: Turboqueue shall be %s\n", - pSiS->TurboQueue ? "enabled" : "disabled"); - } - /* We need identical PDC setting */ - if(pSiS->PDC != pSiSEnt->PDC) { - pSiS->PDC = pSiSEnt->PDC; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent PanelDelayCompensation setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: PanelDelayCompensation shall be %d%s\n", - pSiS->PDC, - (pSiS->PDC == -1) ? " (autodetected)" : ""); - } - /* We need identical TVStandard setting */ - if( (pSiS->OptTVStand != pSiSEnt->OptTVStand) || - (pSiS->NonDefaultPAL != pSiSEnt->NonDefaultPAL) ) { - if(pSiS->OptTVStand != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent TVStandard setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: TVStandard shall be %s\n", - (pSiSEnt->OptTVStand ? - ( (pSiSEnt->NonDefaultPAL == -1) ? "PAL" : - ((pSiSEnt->NonDefaultPAL) ? "PALM" : "PALN") ) - : "NTSC")); - } - pSiS->OptTVStand = pSiSEnt->OptTVStand; - pSiS->NonDefaultPAL = pSiSEnt->NonDefaultPAL; - } - /* We need identical UseROMData setting */ - if(pSiS->OptROMUsage != pSiSEnt->OptROMUsage) { - if(pSiS->OptROMUsage != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent UseROMData setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: Video ROM data usage shall be %s\n", - pSiSEnt->OptROMUsage ? "enabled" : "disabled"); - } - pSiS->OptROMUsage = pSiSEnt->OptROMUsage; - } - /* We need identical DSTN setting */ - if(pSiS->DSTN != pSiSEnt->DSTN) { - pSiS->DSTN = pSiSEnt->DSTN; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent DSTN setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: DSTN shall be %s\n", - pSiS->DSTN ? "enabled" : "disabled"); - } - /* We need identical XvOnCRT2 setting */ - if(pSiS->XvOnCRT2 != pSiSEnt->XvOnCRT2) { - pSiS->XvOnCRT2 = pSiSEnt->XvOnCRT2; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent XvOnCRT2 setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: Xv shall be used on CRT%d\n", - pSiS->XvOnCRT2 ? 2 : 1); - } + /* We need identical NoAccel setting */ if(pSiS->NoAccel != pSiSEnt->NoAccel) { pSiS->NoAccel = pSiSEnt->NoAccel; @@ -2085,159 +3027,55 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) "Master head ruled: Acceleration shall be %s\n", pSiS->NoAccel ? "disabled" : "enabled"); } - /* We need identical ForceCRT1 setting */ - if(pSiS->forceCRT1 != pSiSEnt->forceCRT1) { - if(pSiS->forceCRT1 != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent ForceCRT1 setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: CRT1 shall be %s\n", - pSiSEnt->forceCRT1 ? "enabled" : "disabled"); - } - pSiS->forceCRT1 = pSiSEnt->forceCRT1; - } - /* We need identical TVOverscan setting */ - if(pSiS->OptTVOver != pSiSEnt->OptTVOver) { - if(pSiS->OptTVOver != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVOverscan setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: CHTVOverscan shall be %s\n", - pSiSEnt->OptTVOver ? "true (=overscan)" : "false (=underscan)"); - } - pSiS->OptTVOver = pSiSEnt->OptTVOver; - } - /* We need identical TVSOverscan setting */ - if(pSiS->OptTVSOver != pSiSEnt->OptTVSOver) { - if(pSiS->OptTVSOver != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVSuperOverscan setting\n"); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Master head ruled: CHTVSuperOverscan shall be %s\n", - pSiSEnt->OptTVSOver ? "true" : "false"); - } - pSiS->OptTVSOver = pSiSEnt->OptTVSOver; - } - /* We need identical TV settings */ - if(pSiS->chtvtype != pSiSEnt->chtvtype) { - if(pSiS->chtvtype != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVType setting; set to %s\n", - (pSiSEnt->chtvtype) ? "SCART" : "HDTV"); - } - pSiS->chtvtype = pSiSEnt->chtvtype; - } - if(pSiS->chtvlumabandwidthcvbs != pSiSEnt->chtvlumabandwidthcvbs) { - if(pSiS->chtvlumabandwidthcvbs != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVLumaBandWidthCVBS setting; set to %d\n", - pSiSEnt->chtvlumabandwidthcvbs); - } - pSiS->chtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs; - } - if(pSiS->chtvlumabandwidthsvideo != pSiSEnt->chtvlumabandwidthsvideo) { - if(pSiS->chtvlumabandwidthsvideo != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVLumaBandWidthSVIDEO setting; set to %d\n", - pSiSEnt->chtvlumabandwidthsvideo); - } - pSiS->chtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo; - } - if(pSiS->chtvlumaflickerfilter != pSiSEnt->chtvlumaflickerfilter) { - if(pSiS->chtvlumaflickerfilter != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVLumaFlickerFilter setting; set to %d\n", - pSiSEnt->chtvlumaflickerfilter); - } - pSiS->chtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter; - } - if(pSiS->chtvchromabandwidth != pSiSEnt->chtvchromabandwidth) { - if(pSiS->chtvchromabandwidth != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVChromaBandWidth setting; set to %d\n", - pSiSEnt->chtvchromabandwidth); - } - pSiS->chtvchromabandwidth = pSiSEnt->chtvchromabandwidth; - } - if(pSiS->chtvchromaflickerfilter != pSiSEnt->chtvchromaflickerfilter) { - if(pSiS->chtvchromaflickerfilter != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVChromaFlickerFilter setting; set to %d\n", - pSiSEnt->chtvchromaflickerfilter); - } - pSiS->chtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter; - } - if(pSiS->chtvcvbscolor != pSiSEnt->chtvcvbscolor) { - if(pSiS->chtvcvbscolor != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVCVBSColor setting; set to %s\n", - pSiSEnt->chtvcvbscolor ? "true" : "false"); - } - pSiS->chtvcvbscolor = pSiSEnt->chtvcvbscolor; - } - if(pSiS->chtvtextenhance != pSiSEnt->chtvtextenhance) { - if(pSiS->chtvtextenhance != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVTextEnhance setting; set to %d\n", - pSiSEnt->chtvtextenhance); - } - pSiS->chtvtextenhance = pSiSEnt->chtvtextenhance; - } - if(pSiS->chtvcontrast != pSiSEnt->chtvcontrast) { - if(pSiS->chtvcontrast != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent CHTVContrast setting; set to %d\n", - pSiSEnt->chtvcontrast); - } - pSiS->chtvcontrast = pSiSEnt->chtvcontrast; - } - if(pSiS->sistvedgeenhance != pSiSEnt->sistvedgeenhance) { - if(pSiS->sistvedgeenhance != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent SISTVEdgeEnhance setting; set to %d\n", - pSiSEnt->sistvedgeenhance); - } - pSiS->sistvedgeenhance = pSiSEnt->sistvedgeenhance; - } - if(pSiS->sistvantiflicker != pSiSEnt->sistvantiflicker) { - if(pSiS->sistvantiflicker != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent SISTVAntiFlicker setting; set to %d\n", - pSiSEnt->sistvantiflicker); - } - pSiS->sistvantiflicker = pSiSEnt->sistvantiflicker; - } - if(pSiS->sistvsaturation != pSiSEnt->sistvsaturation) { - if(pSiS->sistvsaturation != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent SISTVSaturation setting; set to %d\n", - pSiSEnt->sistvsaturation); - } - pSiS->sistvsaturation = pSiSEnt->sistvsaturation; - } - if(pSiS->tvxpos != pSiSEnt->tvxpos) { - if(pSiS->tvxpos != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent TVXPosOffset setting; set to %d\n", - pSiSEnt->tvxpos); - } - pSiS->tvxpos = pSiSEnt->tvxpos; - } - if(pSiS->tvypos != pSiSEnt->tvypos) { - if(pSiS->tvypos != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Ignoring inconsistent TVYPosOffset setting; set to %d\n", - pSiSEnt->tvypos); - } - pSiS->tvypos = pSiSEnt->tvypos; - } - if(pSiS->restorebyset != pSiSEnt->restorebyset) { - pSiS->restorebyset = pSiSEnt->restorebyset; - } + + pSiS->TurboQueue = pSiSEnt->TurboQueue; + pSiS->restorebyset = pSiSEnt->restorebyset; + pSiS->AllowHotkey = pSiS->AllowHotkey; + pSiS->OptROMUsage = pSiSEnt->OptROMUsage; + pSiS->OptUseOEM = pSiSEnt->OptUseOEM; + pSiS->forceCRT1 = pSiSEnt->forceCRT1; + pSiS->nocrt2ddcdetection = FALSE; + pSiS->forcecrt2redetection = FALSE; + pSiS->ForceCRT2Type = pSiSEnt->ForceCRT2Type; + pSiS->UsePanelScaler = pSiSEnt->UsePanelScaler; + pSiS->PDC = pSiSEnt->PDC; + pSiS->DSTN = pSiSEnt->DSTN; + pSiS->OptTVStand = pSiSEnt->OptTVStand; + pSiS->chtvtype = pSiSEnt->chtvtype; + pSiS->ForceTVType = pSiSEnt->ForceTVType; + pSiS->OptTVOver = pSiSEnt->OptTVOver; + pSiS->OptTVSOver = pSiSEnt->OptTVSOver; + pSiS->chtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs; + pSiS->chtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo; + pSiS->chtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter; + pSiS->chtvchromabandwidth = pSiSEnt->chtvchromabandwidth; + pSiS->chtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter; + pSiS->chtvcvbscolor = pSiSEnt->chtvcvbscolor; + pSiS->chtvtextenhance = pSiSEnt->chtvtextenhance; + pSiS->chtvcontrast = pSiSEnt->chtvcontrast; + pSiS->sistvedgeenhance = pSiSEnt->sistvedgeenhance; + pSiS->sistvantiflicker = pSiSEnt->sistvantiflicker; + pSiS->sistvsaturation = pSiSEnt->sistvsaturation; + pSiS->sistvcfilter = pSiSEnt->sistvcfilter; + pSiS->sistvyfilter = pSiSEnt->sistvyfilter; + pSiS->sistvcolcalibc = pSiSEnt->sistvcolcalibc; + pSiS->sistvcolcalibf = pSiSEnt->sistvcolcalibf; + pSiS->tvxpos = pSiSEnt->tvxpos; + pSiS->tvypos = pSiSEnt->tvypos; + pSiS->tvxscale = pSiSEnt->tvxscale; + pSiS->tvyscale = pSiSEnt->tvyscale; + pSiS->CRT1gamma = pSiSEnt->CRT1gamma; + pSiS->CRT2gamma = pSiSEnt->CRT2gamma; + pSiS->XvOnCRT2 = pSiSEnt->XvOnCRT2; + pSiS->enablesisctrl = pSiSEnt->enablesisctrl; +#ifdef SIS_CP + SIS_CP_DRIVER_COPYOPTIONS +#endif } } #endif - /* TW: Handle UseROMData and NoOEM options */ + + /* Handle UseROMData, NoOEM and UsePanelScaler options */ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { from = X_PROBED; if(pSiS->OptROMUsage == 0) { @@ -2248,19 +3086,9 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->sishw_ext.UseROM ? "enabled" : "disabled"); if(!pSiS->OptUseOEM) - xf86DrvMsg(pScrn->scrnIndex, from, "Internal OEM LCD/TV data usage is disabled\n"); - - if(pSiS->sbiosn) { - if(pSiS->BIOS) { - FILE *fd = NULL; - int i; - if((fd = fopen(pSiS->sbiosn, "w" ))) { - i = fwrite(pSiS->BIOS, 65536, 1, fd); - fclose(fd); - } - } - xfree(pSiS->sbiosn); - } + xf86DrvMsg(pScrn->scrnIndex, from, "Internal OEM LCD/TV/VGA2 data usage is disabled\n"); + + pSiS->SiS_Pr->UsePanelScaler = pSiS->UsePanelScaler; } /* Do basic configuration */ @@ -2351,12 +3179,18 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->sishw_ext.ulVideoMemorySize = pScrn->videoRam * 1024; pSiS->sishw_ext.bSkipDramSizing = TRUE; - /* TW: Calculate real availMem according to Accel/TurboQueue and - * HWCursur setting. Also, initialize some variables used - * in other modules. + /* Calculate real availMem according to Accel/TurboQueue and + * HWCursur setting. Also, initialize some variables used + * in other modules. */ + pSiS->cursorOffset = 0; + pSiS->CurARGBDest = NULL; + pSiS->CurMonoSrc = NULL; + pSiS->CurFGCol = pSiS->CurBGCol = 0; + switch (pSiS->VGAEngine) { + case SIS_300_VGA: pSiS->TurboQueueLen = 512; if(pSiS->TurboQueue) { @@ -2374,6 +3208,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(pSiSEnt) pSiSEnt->cursorBufferNum = 0; #endif break; + case SIS_315_VGA: if(pSiS->TurboQueue) { pSiS->availMem -= (512*1024); /* Command Queue is 512k */ @@ -2388,18 +3223,19 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(pSiSEnt) pSiSEnt->cursorBufferNum = 0; #endif break; + default: - /* TW: cursorOffset not used in cursor functions for 530 and - * older chips, because the cursor is *above* the TQ. - * On 5597 and older revisions of the 6326, the TQ is - * max 32K, on newer 6326 revisions and the 530 either 30 - * (or 32?) or 62K (or 64?). However, to make sure, we - * use only 30K (or 32?), but reduce the available memory - * by 64, and locate the TQ at the beginning of this last - * 64K block. (We do this that way even when using the - * HWCursor, because the cursor only takes 2K, and the queue - * does not seem to last that far anyway.) - * The TQ must be located at 32KB boundaries. + /* cursorOffset not used in cursor functions for 530 and + * older chips, because the cursor is *above* the TQ. + * On 5597 and older revisions of the 6326, the TQ is + * max 32K, on newer 6326 revisions and the 530 either 30 + * (or 32?) or 62K (or 64?). However, to make sure, we + * use only 30K (or 32?), but reduce the available memory + * by 64, and locate the TQ at the beginning of this last + * 64K block. (We do this that way even when using the + * HWCursor, because the cursor only takes 2K and the + * queue does not seem to last that far anyway.) + * The TQ must be located at 32KB boundaries. */ if(pSiS->RealVideoRam < 3072) { if(pSiS->TurboQueue) { @@ -2411,49 +3247,49 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->CmdQueMaxLen = 32; if(pSiS->TurboQueue) { pSiS->availMem -= (64*1024); - pSiS->CmdQueMaxLen = 900; /* TW: To make sure; should be 992 */ + pSiS->CmdQueMaxLen = 900; /* To make sure; should be 992 */ } else if (pSiS->HWCursor) { pSiS->availMem -= pSiS->CursorSize; } if(pSiS->Chipset == PCI_CHIP_SIS530) { - /* TW: Check if Flat Panel is enabled */ + /* Check if Flat Panel is enabled */ inSISIDXREG(SISSR, 0x0e, tempreg); if(!tempreg & 0x04) pSiS->availMem -= pSiS->CursorSize; - /* TW: Set up mask for MMIO register */ + /* Set up mask for MMIO register */ pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x1FFF : 0x00FF; } else { - /* TW: TQ is never used on 6326/5597, because the accelerator - * always Syncs. So this is just cosmentic work. (And I - * am not even sure that 0x7fff is correct. MMIO 0x83a8 - * holds 0xec0 if (30k) TQ is enabled, 0x20 if TQ disabled. - * The datasheet has no real explanation on the queue length - * if the TQ is enabled. Not syncing and waiting for a - * suitable queue length instead does not work. + /* TQ is never used on 6326/5597, because the accelerator + * always Syncs. So this is just cosmentic work. (And I + * am not even sure that 0x7fff is correct. MMIO 0x83a8 + * holds 0xec0 if (30k) TQ is enabled, 0x20 if TQ disabled. + * The datasheet has no real explanation on the queue length + * if the TQ is enabled. Not syncing and waiting for a + * suitable queue length instead does not work. */ pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x7FFF : 0x003F; } - /* TW: This is to be subtracted from MMIO queue length register contents - * for getting the real Queue length. + /* This is to be subtracted from MMIO queue length register contents + * for getting the real Queue length. */ pSiS->CmdQueLenFix = (pSiS->TurboQueue) ? 32 : 0; } #ifdef SISDUALHEAD - /* TW: In dual head mode, we share availMem equally - so align it - * to 8KB; this way, the address of the FB of the second - * head is aligned to 4KB for mapping. + /* In dual head mode, we share availMem equally - so align it + * to 8KB; this way, the address of the FB of the second + * head is aligned to 4KB for mapping. */ if (pSiS->DualHeadMode) pSiS->availMem &= 0xFFFFE000; #endif - /* TW: Check MaxXFBMem setting */ + /* Check MaxXFBMem setting */ #ifdef SISDUALHEAD - /* TW: Since DRI is not supported in dual head mode, we - don't need MaxXFBMem setting. */ - if (pSiS->DualHeadMode) { + /* Since DRI is not supported in dual head mode, we + don't need the MaxXFBMem setting. */ + if(pSiS->DualHeadMode) { if(pSiS->maxxfbmem) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n"); @@ -2461,9 +3297,9 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->maxxfbmem = pSiS->availMem; } else #endif - if (pSiS->maxxfbmem) { - if (pSiS->maxxfbmem > pSiS->availMem) { - if (pSiS->sisfbMem) { + if(pSiS->maxxfbmem) { + if(pSiS->maxxfbmem > pSiS->availMem) { + if(pSiS->sisfbMem) { pSiS->maxxfbmem = pSiS->sisfbMem * 1024; xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid MaxXFBMem setting. Using sisfb heap start information\n"); @@ -2472,14 +3308,14 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n"); pSiS->maxxfbmem = pSiS->availMem; } - } else if (pSiS->sisfbMem) { - if (pSiS->maxxfbmem > pSiS->sisfbMem * 1024) { + } else if(pSiS->sisfbMem) { + if(pSiS->maxxfbmem > pSiS->sisfbMem * 1024) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MaxXFBMem beyond sisfb heap start. Using sisfb heap start information\n"); pSiS->maxxfbmem = pSiS->sisfbMem * 1024; } } - } else if (pSiS->sisfbMem) { + } else if(pSiS->sisfbMem) { pSiS->maxxfbmem = pSiS->sisfbMem * 1024; } else pSiS->maxxfbmem = pSiS->availMem; @@ -2487,37 +3323,122 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %dK of framebuffer memory\n", pSiS->maxxfbmem / 1024); - /* TW: Check if the chipset supports two video overlays */ - pSiS->Flags650 = 0; - if ( (!pSiS->NoXvideo) && - ( pSiS->VGAEngine == SIS_300_VGA || - pSiS->VGAEngine == SIS_315_VGA || - pSiS->Chipset == PCI_CHIP_SIS530 || - pSiS->Chipset == PCI_CHIP_SIS6326 || - pSiS->Chipset == PCI_CHIP_SIS5597 ) ) { + /* Check if the chipset supports two video overlays */ + if( (!pSiS->NoXvideo) && + ( pSiS->VGAEngine == SIS_300_VGA || + pSiS->VGAEngine == SIS_315_VGA || + pSiS->Chipset == PCI_CHIP_SIS530 || + pSiS->Chipset == PCI_CHIP_SIS6326 || + pSiS->Chipset == PCI_CHIP_SIS5597 ) ) { pSiS->hasTwoOverlays = FALSE; switch (pSiS->Chipset) { case PCI_CHIP_SIS300: case PCI_CHIP_SIS630: - case PCI_CHIP_SIS550: - case PCI_CHIP_SIS330: /* ? */ - pSiS->hasTwoOverlays = TRUE; + case PCI_CHIP_SIS550: + pSiS->hasTwoOverlays = TRUE; + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL; break; + case PCI_CHIP_SIS315PRO: + pSiS->ChipFlags |= SiSCF_LARGEOVERLAY; + break; + case PCI_CHIP_SIS330: + pSiS->ChipFlags |= SiSCF_LARGEOVERLAY; + break; + case PCI_CHIP_SIS660: + { + static const char *id660str[] = { + "660 ?", "660 ?", "660 ?", "660 ?", + "660 ?", "660 ?", "660 ?", "660 ?", + "660 ?", "660 ?", "660 ?", "660 ?", + "660 ?", "660 ?", "660 ?", "660 ?" + }; + pSiS->ChipFlags |= SiSCF_LARGEOVERLAY; + /* This is a wild guess */ + pSiS->hasTwoOverlays = TRUE; + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL; + if(pSiS->sishw_ext.jChipType == SIS_660) { + inSISIDXREG(SISCR, 0x5f, CR5F); + CR5F &= 0xf0; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS660 revision ID %x (%s)\n", CR5F, id660str[CR5F >> 4]); + } + break; + } case PCI_CHIP_SIS650: { + unsigned char tempreg1, tempreg2; static const char *id650str[] = { - "0", "0", "0", "0", - "0 A0 AA", "0 A2 CA", "0", "0", - "0M A0", "0M A1 AA", "1 A0 AA", "1 A1 AA" - "0", "0", "0", "0" + "650", "650", "650", "650", + "650 A0 AA", "650 A2 CA", "650", "650", + "M650 A0", "M650 A1 AA","651 A0 AA", "651 A1 AA", + "M650", "65?", "651", "65?" }; - inSISIDXREG(SISCR, 0x5F, CR5F); - CR5F &= 0xf0; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "SiS650 revision ID %x (SiS65%s)\n", CR5F, id650str[CR5F >> 4]); - if((CR5F == 0x80) || (CR5F == 0x90) || (CR5F == 0xa0) || (CR5F == 0xb0)) { - pSiS->hasTwoOverlays = TRUE; /* TW: This is an M650 or 651 */ - pSiS->Flags650 |= SiS650_LARGEOVERLAY; + pSiS->ChipFlags |= SiSCF_LARGEOVERLAY; + if(pSiS->sishw_ext.jChipType == SIS_650) { + inSISIDXREG(SISCR, 0x5f, CR5F); + CR5F &= 0xf0; + andSISIDXREG(SISCR, 0x5c, 0x07); + inSISIDXREG(SISCR, 0x5c, tempreg1); + tempreg1 &= 0xf8; + setSISIDXREG(SISCR, 0x5c, 0x07, 0xf8); + inSISIDXREG(SISCR, 0x5c, tempreg2); + tempreg2 &= 0xf8; + if((!tempreg1) || (tempreg2)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS650 revision ID %x (%s)\n", CR5F, id650str[CR5F >> 4]); + if(CR5F & 0x80) { + pSiS->hasTwoOverlays = TRUE; /* M650 or 651 */ + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL; + } + switch(CR5F) { + case 0xa0: + case 0xb0: + case 0xe0: + pSiS->ChipFlags |= SiSCF_Is651; + break; + case 0x80: + case 0x90: + case 0xc0: + pSiS->ChipFlags |= SiSCF_IsM650; + break; + } + } else { + pSiS->hasTwoOverlays = TRUE; + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL; + switch(CR5F) { + case 0x90: + inSISIDXREG(SISCR, 0x5c, tempreg1); + tempreg1 &= 0xf8; + switch(tempreg1) { + case 0x00: + pSiS->ChipFlags |= SiSCF_IsM652; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiSM652 revision ID %x\n", CR5F); + break; + case 0x40: + pSiS->ChipFlags |= SiSCF_IsM653; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiSM653 revision ID %x\n", CR5F); + break; + default: + pSiS->ChipFlags |= SiSCF_IsM650; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiSM650 revision ID %x\n", CR5F); + break; + } + break; + case 0xb0: + pSiS->ChipFlags |= SiSCF_Is652; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS652 revision ID %x\n", CR5F); + break; + default: + pSiS->ChipFlags |= SiSCF_IsM650; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiSM650 revision ID %x\n", CR5F); + break; + } + } } break; } @@ -2528,10 +3449,12 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->hasTwoOverlays ? "s" : ""); } - /* TW: Backup VB connection and CRT1 on/off register */ + /* Backup VB connection and CRT1 on/off register */ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { inSISIDXREG(SISCR, 0x32, pSiS->oldCR32); inSISIDXREG(SISCR, 0x17, pSiS->oldCR17); + inSISIDXREG(SISCR, 0x63, pSiS->oldCR63); + inSISIDXREG(SISSR, 0x1f, pSiS->oldSR1F); pSiS->postVBCR32 = pSiS->oldCR32; } @@ -2540,49 +3463,114 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) else pSiS->CRT1off = 1; } else pSiS->CRT1off = -1; - /* TW: There are some strange machines out there which require a special - * manupulation of ISA bridge registers in order to make the Chrontel - * work. Try to find out if we're running on such a machine. + /* There are some machines out there which require a special + * setup of the GPIO registers in order to make the Chrontel + * work. Try to find out if we're running on such a machine. + * Furthermore, there is some highly customized hardware, + * which requires some non-standard LVDS timing. Since the + * vendors don't seem to care about PCI subsystem ID's we + * need to find out using the BIOS version and date strings. */ pSiS->SiS_Pr->SiS_ChSW = FALSE; if(pSiS->Chipset == PCI_CHIP_SIS630) { - int i=0; - do { - if(mychswtable[i].subsysVendor == pSiS->PciInfo->subsysVendor && - mychswtable[i].subsysCard == pSiS->PciInfo->subsysCard) { + int i = 0; + do { + if(mychswtable[i].subsysVendor == pSiS->PciInfo->subsysVendor && + mychswtable[i].subsysCard == pSiS->PciInfo->subsysCard) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI subsystem ID found in list for Chrontel/GPIO setup\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Vendor/Card: %s %s (ID %04x)\n", + mychswtable[i].vendorName, + mychswtable[i].cardName, + pSiS->PciInfo->subsysCard); + pSiS->SiS_Pr->SiS_ChSW = TRUE; + break; + } + i++; + } while(mychswtable[i].subsysVendor != 0); + } + + if((pSiS->sishw_ext.UseROM) && (pSiS->SiS_Pr->SiS_CustomT == CUT_NONE)) { + int i = 0, j; + unsigned short bversptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8); + BOOLEAN footprint; + unsigned long chksum = 0; + + for(i=0; i<32768; i++) chksum += pSiS->BIOS[i]; + + i = 0; + do { + if( (mycustomttable[i].chipID == pSiS->sishw_ext.jChipType) && + ((!strlen(mycustomttable[i].biosversion)) || + (!strncmp(mycustomttable[i].biosversion, (char *)&pSiS->BIOS[bversptr], + strlen(mycustomttable[i].biosversion)))) && + ((!strlen(mycustomttable[i].biosdate)) || + (!strncmp(mycustomttable[i].biosdate, (char *)&pSiS->BIOS[0x2c], + strlen(mycustomttable[i].biosdate)))) && + ((!mycustomttable[i].bioschksum) || + (mycustomttable[i].bioschksum == chksum)) && + (mycustomttable[i].pcisubsysvendor == pSiS->PciInfo->subsysVendor) && + (mycustomttable[i].pcisubsyscard == pSiS->PciInfo->subsysCard) ) { + footprint = TRUE; + for(j=0; j<5; j++) { + if(mycustomttable[i].biosFootprintAddr[j]) { + if(pSiS->BIOS[mycustomttable[i].biosFootprintAddr[j]] != mycustomttable[i].biosFootprintData[j]) + footprint = FALSE; + } + } + if(footprint) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "PCI card/vendor found in list for Chrontel/ISA bridge poking\n"); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Vendor: %s (ID %04x)\n", - mychswtable[i].vendorName, pSiS->PciInfo->subsysCard); - pSiS->SiS_Pr->SiS_ChSW = TRUE; - } - i++; - } while(mychswtable[i].subsysVendor != 0); + "Identified %s %s, special timing applies\n", + mycustomttable[i].vendorName, mycustomttable[i].cardName); + pSiS->SiS_Pr->SiS_CustomT = mycustomttable[i].SpecialID; + break; + } + } + i++; + } while(mycustomttable[i].chipID); } - /* TW: Detect video bridge and sense connected devices */ + /* Detect video bridge and sense connected devices */ SISVGAPreInit(pScrn); - /* TW: Detect CRT1 */ + /* Detect CRT1 */ SISCRT1PreInit(pScrn); - /* TW: Detect CRT2-LCD and LCD size */ + /* Detect CRT2-LCD and LCD size */ SISLCDPreInit(pScrn); - /* TW: Detect CRT2-TV and PAL/NTSC mode */ + /* Detect CRT2-TV and PAL/NTSC mode */ SISTVPreInit(pScrn); - /* TW: Detect CRT2-VGA */ + /* Detect CRT2-VGA */ SISCRT2PreInit(pScrn); - /* TW: Backup detected CRT2 devices */ - pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD | CRT2_TV | CRT2_VGA); + /* Backup detected CRT2 devices */ + pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD | CRT2_TV | CRT2_VGA | TV_AVIDEO | TV_SVIDEO | TV_SCART); - /* TW: Eventually overrule detected CRT2 type */ + if((pSiS->VBFlags & VB_SISBRIDGE) || + ((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_701x))) { + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTPALMN; + } + if((pSiS->VBFlags & VB_SISBRIDGE) || + ((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_700x))) { + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTTVPOS; + } + if((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_700x)) { + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTSOVER; + } + + /* Eventually overrule detected CRT2 type + * If no type forced, use the detected devices in the order VGA2->TV->LCD + * Since the Chrontel 7005 sometimes delivers wrong detection results, + * we use a different order on such machines (LCD->TV) + */ if(pSiS->ForceCRT2Type == CRT2_DEFAULT) { if(pSiS->VBFlags & CRT2_VGA) pSiS->ForceCRT2Type = CRT2_VGA; + else if((pSiS->VBFlags & CRT2_TV) && (!((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->VGAEngine == SIS_300_VGA)))) + pSiS->ForceCRT2Type = CRT2_TV; else if(pSiS->VBFlags & CRT2_LCD) pSiS->ForceCRT2Type = CRT2_LCD; - else if(pSiS->VBFlags & CRT2_TV) - pSiS->ForceCRT2Type = CRT2_TV; + else if(pSiS->VBFlags & CRT2_TV) + pSiS->ForceCRT2Type = CRT2_TV; } switch(pSiS->ForceCRT2Type) { @@ -2608,8 +3596,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "LVDS does not support secondary VGA\n"); break; - } - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + } else if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "SiS30xLV bridge does not support secondary VGA\n"); break; @@ -2623,8 +3610,17 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) default: pSiS->VBFlags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA); } + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if( (pSiS->VBFlags & (VB_301 | VB_301B | VB_302B | VB_301LV | VB_302LV)) && + (!((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD))) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CRT2 gamma correction is %s\n", + pSiS->CRT2gamma ? "enabled" : "disabled"); + } + } - /* TW: Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART) */ + /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART) */ if(pSiS->ForceTVType != -1) { if(pSiS->VBFlags & VB_SISBRIDGE) { pSiS->VBFlags &= ~(TV_INTERFACE); @@ -2632,15 +3628,17 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } } - /* TW: Handle ForceCRT1 option */ + /* Handle ForceCRT1 option */ pSiS->CRT1changed = FALSE; if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { usScratchCR17 = pSiS->oldCR17; + usScratchCR63 = pSiS->oldCR63; + usScratchSR1F = pSiS->oldSR1F; usScratchCR32 = pSiS->postVBCR32; if(pSiS->VESA != 1) { - /* TW: Copy forceCRT1 option to CRT1off if option is given */ + /* Copy forceCRT1 option to CRT1off if option is given */ #ifdef SISDUALHEAD - /* TW: In DHM, handle this option only for master head, not the slave */ + /* In DHM, handle this option only for master head, not the slave */ if( (pSiS->forceCRT1 != -1) && (!(pSiS->DualHeadMode && pSiS->SecondHead)) ) { #else @@ -2650,20 +3648,36 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) "CRT1 detection overruled by ForceCRT1 option\n"); if(pSiS->forceCRT1) { pSiS->CRT1off = 0; - if (!(usScratchCR17 & 0x80)) pSiS->CRT1changed = TRUE; + if(pSiS->VGAEngine == SIS_300_VGA) { + if(!(usScratchCR17 & 0x80)) pSiS->CRT1changed = TRUE; + } else { + if(usScratchCR63 & 0x40) pSiS->CRT1changed = TRUE; + } usScratchCR17 |= 0x80; usScratchCR32 |= 0x20; + usScratchCR63 &= ~0x40; + usScratchSR1F &= ~0xc0; } else { if( ! ( (pScrn->bitsPerPixel == 8) && - ( (pSiS->VBFlags & VB_LVDS) || - ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) { + ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) || + ((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD)) ) ) ) { pSiS->CRT1off = 1; - if (usScratchCR17 & 0x80) pSiS->CRT1changed = TRUE; + if(pSiS->VGAEngine == SIS_300_VGA) { + if(usScratchCR17 & 0x80) pSiS->CRT1changed = TRUE; + } else { + if(!(usScratchCR63 & 0x40)) pSiS->CRT1changed = TRUE; + } usScratchCR32 &= ~0x20; - /* TW: We must not actually switch off CRT1 before we changed the mode! */ + /* We must not actually switch off CRT1 before we changed the mode! */ } } + /* Here we can write to CR17 even on 315 series as we only ENABLE + * the bit here + */ outSISIDXREG(SISCR, 0x17, usScratchCR17); + if(pSiS->VGAEngine == SIS_315_VGA) { + outSISIDXREG(SISCR, 0x63, usScratchCR63); + } outSISIDXREG(SISCR, 0x32, usScratchCR32); if(pSiS->CRT1changed) { outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ @@ -2672,29 +3686,30 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1 status changed by ForceCRT1 option\n"); } + outSISIDXREG(SISSR, 0x1f, usScratchSR1F); } } - /* TW: Store the new VB connection register contents for later mode changes */ + /* Store the new VB connection register contents for later mode changes */ pSiS->newCR32 = usScratchCR32; } - /* TW: Check if CRT1 used (or needed; this eg. if no CRT2 detected) */ - if (pSiS->VBFlags & VB_VIDEOBRIDGE) { - - /* TW: No CRT2 output? Then we NEED CRT1! - * We also need CRT1 if depth = 8 and bridge=LVDS|630+301B + /* Check if CRT1 used (or needed; this eg. if no CRT2 detected) */ + if(pSiS->VBFlags & VB_VIDEOBRIDGE) { + + /* No CRT2 output? Then we NEED CRT1! + * We also need CRT1 if depth = 8 and bridge=LVDS|301B-DH */ - if ( (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) || - ( (pScrn->bitsPerPixel == 8) && - ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) || - ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) { + if( (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) || + ( (pScrn->bitsPerPixel == 8) && + ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) || + ((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD)) ) ) ) { pSiS->CRT1off = 0; } - /* TW: No CRT2 output? Then we can't use Xv on CRT2 */ - if (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) + /* No CRT2 output? Then we can't use Xv on CRT2 */ + if(!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) pSiS->XvOnCRT2 = FALSE; - } else { /* TW: no video bridge? */ + } else { /* no video bridge? */ /* Then we NEED CRT1... */ pSiS->CRT1off = 0; @@ -2702,22 +3717,24 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->XvOnCRT2 = FALSE; } - /* TW: Handle TVStandard option */ + /* Handle TVStandard option */ if(pSiS->NonDefaultPAL != -1) { if( (!(pSiS->VBFlags & VB_SISBRIDGE)) && (!((pSiS->VBFlags & VB_CHRONTEL)) && (pSiS->ChrontelType == CHRONTEL_701x)) ) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PALM and PALN only supported on Chrontel 701x and SiS30x/B/LV\n"); - pSiS->NonDefaultPAL = -1; + pSiS->NonDefaultPAL = -1; pSiS->VBFlags &= ~(TV_PALN | TV_PALM); + pSiS->SiS_SD_Flags &= ~SiS_SD_SUPPORTPALMN; } } if(pSiS->NonDefaultPAL != -1) { if((pSiS->Chipset == PCI_CHIP_SIS300) || (pSiS->Chipset == PCI_CHIP_SIS540)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PALM and PALN not supported on SiS300 and SiS540\n"); - pSiS->NonDefaultPAL = -1; + pSiS->NonDefaultPAL = -1; pSiS->VBFlags &= ~(TV_PALN | TV_PALM); + pSiS->SiS_SD_Flags &= ~SiS_SD_SUPPORTPALMN; } } if(pSiS->OptTVStand != -1) { @@ -2733,39 +3750,83 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Option TVStandard ignored for SCART and 480i HDTV\n"); } + } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { pSiS->SiS6326Flags &= ~SIS6326_TVPAL; if(pSiS->OptTVStand) pSiS->SiS6326Flags |= SIS6326_TVPAL; } } - /* TW: Do some checks */ + /* SCART only supported for PAL */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if((pSiS->VBFlags & VB_SISBRIDGE) && (pSiS->VBFlags & TV_SCART)) { + pSiS->VBFlags &= ~(TV_NTSC | TV_PALN | TV_PALM); + pSiS->VBFlags |= TV_PAL; + pSiS->OptTVStand = 1; + pSiS->NonDefaultPAL = -1; + } + } + + + +#ifdef SIS_CP + SIS_CP_DRIVER_RECONFIGOPT +#endif + + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + if(pSiS->sis6326tvplug != -1) { + pSiS->SiS6326Flags &= ~(SIS6326_TVSVIDEO | SIS6326_TVCVBS); + pSiS->SiS6326Flags |= SIS6326_TVDETECTED; + if(pSiS->sis6326tvplug == 1) pSiS->SiS6326Flags |= SIS6326_TVCVBS; + else pSiS->SiS6326Flags |= SIS6326_TVSVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "SiS6326 TV plug type detection overruled by %s\n", + (pSiS->SiS6326Flags & SIS6326_TVCVBS) ? "COMPOSITE" : "SVIDEO"); + } + } + + /* Do some checks */ if(pSiS->OptTVOver != -1) { if(pSiS->VBFlags & VB_CHRONTEL) { pSiS->UseCHOverScan = pSiS->OptTVOver; } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "CHTVOverscan option only supported on CHRONTEL 70xx\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CHTVOverscan only supported on CHRONTEL 70xx\n"); pSiS->UseCHOverScan = -1; } } else pSiS->UseCHOverScan = -1; - + if(pSiS->sistvedgeenhance != -1) { if(!(pSiS->VBFlags & VB_301)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SISTVEdgeEnhance option only supported on SiS301\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SISTVEdgeEnhance only supported on SiS301\n"); pSiS->sistvedgeenhance = -1; } } - /* TW: Determine CRT1<>CRT2 mode + /* Do some MergedFB mode initialisation */ +#ifdef SISMERGED + if(pSiS->MergedFB) { + pSiS->CRT2pScrn = xalloc(sizeof(ScrnInfoRec)); + if(!pSiS->CRT2pScrn) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate memory for merged pScrn, MergedFB mode is disabled\n"); + pSiS->MergedFB = FALSE; + } else { + memcpy(pSiS->CRT2pScrn, pScrn, sizeof(ScrnInfoRec)); + } + } +#endif + + + /* Determine CRT1<>CRT2 mode * Note: When using VESA or if the bridge is in slavemode, display * is ALWAYS in MIRROR_MODE! * This requires extra checks in functions using this flag! * (see sis_video.c for example) */ if(pSiS->VBFlags & DISPTYPE_DISP2) { - if(pSiS->CRT1off) { /* TW: CRT2 only ------------------------------- */ + if(pSiS->CRT1off) { /* CRT2 only ------------------------------- */ #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -2773,15 +3834,25 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(pSiSEnt) pSiSEnt->DisableDual = TRUE; if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + pSiS->pInt = NULL; sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); SISFreeRec(pScrn); return FALSE; } #endif +#ifdef SISMERGED + if(pSiS->MergedFB) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT1 not detected or forced off. MergedFB mode disabled.\n"); + if(pSiS->CRT2pScrn) xfree(pSiS->CRT2pScrn); + pSiS->CRT2pScrn = NULL; + pSiS->MergedFB = FALSE; + } +#endif pSiS->VBFlags |= VB_DISPMODE_SINGLE; - /* TW: No CRT1? Then we use the video overlay on CRT2 */ + /* No CRT1? Then we use the video overlay on CRT2 */ pSiS->XvOnCRT2 = TRUE; - } else /* TW: CRT1 and CRT2 - mirror or dual head ----- */ + } else /* CRT1 and CRT2 - mirror or dual head ----- */ #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { pSiS->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1); @@ -2793,8 +3864,18 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->VESA = 0; } else #endif +#ifdef SISMERGED + if(pSiS->MergedFB) { + pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1); + if(pSiS->VESA != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VESA option not used in MergedFB mode. VESA disabled.\n"); + } + pSiS->VESA = 0; + } else +#endif pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1); - } else { /* TW: CRT1 only ------------------------------- */ + } else { /* CRT1 only ------------------------------- */ #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -2802,11 +3883,22 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) "Dual Head mode can't initialize.\n"); if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + pSiS->pInt = NULL; sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); SISFreeRec(pScrn); return FALSE; } #endif +#ifdef SISMERGED + if(pSiS->MergedFB) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No CRT2 output selected or no bridge detected. " + "MergedFB mode disabled.\n"); + if(pSiS->CRT2pScrn) xfree(pSiS->CRT2pScrn); + pSiS->CRT2pScrn = NULL; + pSiS->MergedFB = FALSE; + } +#endif pSiS->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1); } @@ -2815,30 +3907,30 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if ( (!pSiS->NoXvideo) && (!pSiS->hasTwoOverlays) ) { xf86DrvMsg(pScrn->scrnIndex, from, - "Using Xv overlay on CRT%d\n", + "Using Xv overlay by default on CRT%d\n", pSiS->XvOnCRT2 ? 2 : 1); } } - /* TW: Init Ptrs for Save/Restore functions and calc MaxClock */ + /* Init Ptrs for Save/Restore functions and calc MaxClock */ SISDACPreInit(pScrn); /* ********** end of VBFlags setup ********** */ - /* TW: VBFlags are initialized now. Back them up for SlaveMode modes. */ + /* VBFlags are initialized now. Back them up for SlaveMode modes. */ pSiS->VBFlags_backup = pSiS->VBFlags; - /* TW: Find out about paneldelaycompensation and evaluate option */ + /* Find out about paneldelaycompensation and evaluate option */ pSiS->sishw_ext.pdc = 0; if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_LVDS | VB_301B | VB_302B)) { - /* TW: Save the current PDC if the panel is used at the moment. - * This seems by far the safest way to find out about it. - * If the system is using an old version of sisfb, we can't - * trust the pdc register value. If sisfb saved the pdc for - * us, use it. + if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) { + /* Save the current PDC if the panel is used at the moment. + * This seems by far the safest way to find out about it. + * If the system is using an old version of sisfb, we can't + * trust the pdc register value. If sisfb saved the pdc for + * us, use it. */ if(pSiS->sisfbpdc) { pSiS->sishw_ext.pdc = pSiS->sisfbpdc; @@ -2872,7 +3964,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(mypdctable[i].subsysVendor == pSiS->PciInfo->subsysVendor && mypdctable[i].subsysCard == pSiS->PciInfo->subsysCard) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "PCI card/vendor found in list for non-default PanelDelayCompensation\n"); + "PCI card/vendor identified for non-default PanelDelayCompensation\n"); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Vendor: %s, card: %s (ID %04x), PanelDelayCompensation: %d\n", mypdctable[i].vendorName, mypdctable[i].cardName, @@ -2918,10 +4010,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } #ifdef SISDUALHEAD - /* TW: In dual head mode, both heads (currently) share the maxxfbmem equally. - * If memory sharing is done differently, the following has to be changed; - * the other modules (eg. accel and Xv) use dhmOffset for hardware - * pointer settings relative to VideoRAM start and won't need to be changed. + /* In dual head mode, both heads (currently) share the maxxfbmem equally. + * If memory sharing is done differently, the following has to be changed; + * the other modules (eg. accel and Xv) use dhmOffset for hardware + * pointer settings relative to VideoRAM start and won't need to be changed. */ if (pSiS->DualHeadMode) { if (pSiS->SecondHead == FALSE) { @@ -2954,55 +4046,64 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->dhmOffset = 0; #endif - /* TW: Note: Do not use availMem for anything from now. Use - * maxxfbmem instead. (availMem does not take dual head - * mode into account.) + /* Note: Do not use availMem for anything from now. Use + * maxxfbmem instead. (availMem does not take dual head + * mode into account.) */ - /* TW: Now for something completely different: DDC. - For 300 and 310/325 series, we provide our - own functions (in order to probe CRT2 as well) - If these fail, use the VBE. - All other chipsets will use VBE. No need to re-invent - the wheel there. + + /* Now for something completely different: DDC. + * For 300 and 315 series, we provide our + * own functions (in order to probe CRT2 as well) + * If these fail, use the VBE. + * All other chipsets will use VBE. No need to re-invent + * the wheel there. */ pSiS->pVbe = NULL; didddc2 = FALSE; if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { - if(xf86LoadSubModule(pScrn, "ddc")) { + if(xf86LoadSubModule(pScrn, "ddc")) { xf86LoaderReqSymLists(ddcSymbols, NULL); if((pMonitor = SiSDoPrivateDDC(pScrn))) { didddc2 = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "DDC monitor info:\n"); + "CRT%d DDC monitor info: ************************************\n", +#ifdef SISDUALHEAD + pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) : +#endif + (pSiS->CRT1off ? 2 : 1)); xf86PrintEDID(pMonitor); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "End of DDC monitor info\n"); + "End of CRT%d DDC monitor info ******************************\n", +#ifdef SISDUALHEAD + pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) : +#endif + (pSiS->CRT1off ? 2 : 1)); xf86SetDDCproperties(pScrn, pMonitor); pScrn->monitor->DDC = pMonitor; } - } + } } #ifdef SISDUALHEAD - /* TW: In dual head mode, probe DDC using VBE only for CRT1 (second head) */ + /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */ if((pSiS->DualHeadMode) && (!didddc2) && (!pSiS->SecondHead)) didddc2 = TRUE; #endif - /* TW: If CRT1 is off (eventually forced), skip DDC */ + /* If CRT1 is off (eventually forced), skip DDC via VBE */ if((!didddc2) && (pSiS->CRT1off)) didddc2 = TRUE; - /* TW: Now (re-)load and initialize the DDC module */ + /* Now (re-)load and initialize the DDC module */ if(!didddc2) { if(xf86LoadSubModule(pScrn, "ddc")) { xf86LoaderReqSymLists(ddcSymbols, NULL); - /* TW: Now load and initialize VBE module. */ + /* Now load and initialize VBE module. */ if(xf86LoadSubModule(pScrn, "vbe")) { xf86LoaderReqSymLists(vbeSymbols, NULL); #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) @@ -3023,10 +4124,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(pSiS->pVbe) { if((pMonitor = vbeDoEDID(pSiS->pVbe,NULL))) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "VBE DDC monitor info:\n"); + "VBE CRT1 DDC monitor info:\n"); xf86SetDDCproperties(pScrn, xf86PrintEDID(pMonitor)); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "End of VBE DDC monitor info:\n"); + "End of VBE CRT1 DDC monitor info:\n"); pScrn->monitor->DDC = pMonitor; } } else { @@ -3036,16 +4137,107 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } } -#if 0 /* TW: DDC1 obviously no longer supported by SiS chipsets */ - if (!ret && pSiS->ddc1Read) - xf86SetDDCproperties(pScrn, xf86PrintEDID(xf86DoEDID_DDC1( - pScrn->scrnIndex,vgaHWddc1SetSpeed,pSiS->ddc1Read ))); +#ifdef SISMERGED + if(pSiS->MergedFB) { + pSiS->CRT2pScrn->monitor = xalloc(sizeof(MonRec)); + if(pSiS->CRT2pScrn->monitor) { + DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL; + memcpy(pSiS->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec)); + pSiS->CRT2pScrn->monitor->DDC = NULL; + pSiS->CRT2pScrn->monitor->Modes = NULL; + tempm = pScrn->monitor->Modes; + while(tempm) { + if(!(newm = xalloc(sizeof(DisplayModeRec)))) break; + memcpy(newm, tempm, sizeof(DisplayModeRec)); + if(!(newm->name = xalloc(strlen(tempm->name) + 1))) { + xfree(newm); + break; + } + strcpy(newm->name, tempm->name); + if(!pSiS->CRT2pScrn->monitor->Modes) pSiS->CRT2pScrn->monitor->Modes = newm; + if(currentm) { + currentm->next = newm; + newm->prev = currentm; + } + currentm = newm; + tempm = tempm->next; + } + if(pSiS->CRT2HSync) { + pSiS->CRT2pScrn->monitor->nHsync = + SiSStrToRanges(pSiS->CRT2pScrn->monitor->hsync, pSiS->CRT2HSync); + } + if(pSiS->CRT2VRefresh) { + pSiS->CRT2pScrn->monitor->nVrefresh = + SiSStrToRanges(pSiS->CRT2pScrn->monitor->vrefresh, pSiS->CRT2VRefresh); + } + if((pMonitor = SiSInternalDDC(pSiS->CRT2pScrn, 1))) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CRT2 DDC monitor info: ************************************\n"); + xf86PrintEDID(pMonitor); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "End of CRT2 DDC monitor info ******************************\n"); + xf86SetDDCproperties(pSiS->CRT2pScrn, pMonitor); + pSiS->CRT2pScrn->monitor->DDC = pMonitor; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Failed to read DDC data for CRT2\n"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate memory for CRT2 monitor, MergedFB mode disabled.\n"); + if(pSiS->CRT2pScrn) xfree(pSiS->CRT2pScrn); + pSiS->CRT2pScrn = NULL; + pSiS->MergedFB = FALSE; + } + } #endif + /* If there is no HSync or VRefresh data for the monitor, + * derive it from DDC data. (Idea taken from radeon driver) + */ + if(pScrn->monitor->DDC) { + if(pScrn->monitor->nHsync <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Substituting missing CRT%d monitor HSync data by DDC data\n", + pSiS->CRT1off ? 2 : 1); + SiSSetSyncRangeFromEdid(pScrn, 1); + } + if(pScrn->monitor->nVrefresh <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Substituting missing CRT%d monitor VRefresh data by DDC data\n", + pSiS->CRT1off ? 2 : 1); + SiSSetSyncRangeFromEdid(pScrn, 0); + } + } + +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(pSiS->CRT2pScrn->monitor->DDC) { + if(pSiS->CRT2pScrn->monitor->nHsync <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Substituting missing CRT2 monitor HSync data by DDC data\n"); + SiSSetSyncRangeFromEdid(pSiS->CRT2pScrn, 1); + } + if(pSiS->CRT2pScrn->monitor->nVrefresh <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Substituting missing CRT2 monitor VRefresh data by DDC data\n"); + SiSSetSyncRangeFromEdid(pSiS->CRT2pScrn, 0); + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "------------------------ CRT1 setup -------------------------\n"); + } +#endif /* end of DDC */ + /* From here, we mainly deal with clocks and modes */ + /* Set the min pixel clock */ - pSiS->MinClock = 12000; /* XXX Guess, need to check this (TW: good for even 50Hz interlace) */ + pSiS->MinClock = 5000; + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + pSiS->MinClock = 12000; + } xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", pSiS->MinClock / 1000); @@ -3091,106 +4283,98 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->interlaceAllowed = TRUE; clockRanges->doubleScanAllowed = TRUE; - /* TW: If there is no HSync or VRefresh data for the monitor, - derive it from DDC data. (Idea taken from radeon driver) - */ - if(pScrn->monitor->DDC) { - if(pScrn->monitor->nHsync <= 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Substituting missing monitor HSync data by DDC data\n"); - SiSSetSyncRangeFromEdid(pScrn, 1); - } - if(pScrn->monitor->nVrefresh <= 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Substituting missing monitor VRefresh data by DDC data\n"); - SiSSetSyncRangeFromEdid(pScrn, 0); - } - } - /* - * TW: Since we have lots of built-in modes for 300/310/325/330 series + * TW: Since we have lots of built-in modes for 300/315/330 series * with vb support, we replace the given default mode list with our - * own. In case the video bridge is to be used, no other than our - * built-in modes are supported; therefore, delete the entire modelist - * given. + * own. In case the video bridge is to be used, we only allow other + * modes if + * -) vbtype is 301, 301B or 302B, and + * -) crt2 device is not TV. */ - - pSiS->HaveCustomModes = FALSE; if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { - if(!(pSiS->noInternalModes)) { - if((mymodes = SiSBuildBuiltInModeList(pScrn))) { -#ifdef SISDUALHEAD - if( (pSiS->UseVESA) || - ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) || - ((!pSiS->DualHeadMode) && (pSiS->VBFlags & DISPTYPE_DISP2)) ) { -#else - if((pSiS->UseVESA) || (pSiS->VBFlags & DISPTYPE_DISP2)) { -#endif - while(pScrn->monitor->Modes) - xf86DeleteMode(&pScrn->monitor->Modes, pScrn->monitor->Modes); - pScrn->monitor->Modes = mymodes; - } else { - delmode = pScrn->monitor->Modes; - while(delmode) { - if(delmode->type & M_T_DEFAULT) { - tempmode = delmode->next; - xf86DeleteMode(&pScrn->monitor->Modes, delmode); - delmode = tempmode; - } else { - delmode = delmode->next; - } - } - tempmode = pScrn->monitor->Modes; - if(tempmode) pSiS->HaveCustomModes = TRUE; - pScrn->monitor->Modes = mymodes; - while(mymodes) { - if(!mymodes->next) break; - else mymodes = mymodes->next; - } - mymodes->next = tempmode; - if(tempmode) { - tempmode->prev = mymodes; - } - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Replaced %s mode list with built-in modes\n", - pSiS->HaveCustomModes ? "default" : "entire"); + if(!(pSiS->noInternalModes)) { + BOOLEAN acceptcustommodes = TRUE; + BOOLEAN includelcdmodes = TRUE; + BOOLEAN isfordvi = FALSE; + if(pSiS->UseVESA) { + acceptcustommodes = FALSE; + includelcdmodes = FALSE; + } +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->SecondHead) { + if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B)) { + if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; + if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; + if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE; + } else { + acceptcustommodes = FALSE; + includelcdmodes = FALSE; + } + } else { + includelcdmodes = FALSE; + } + } else +#endif +#ifdef SISMERGED + if(pSiS->MergedFB) + includelcdmodes = FALSE; + else +#endif + if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B)) { + if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; + if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; + if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE; + } else if(pSiS->VBFlags & CRT2_ENABLE) { + acceptcustommodes = FALSE; + includelcdmodes = FALSE; + } else { + includelcdmodes = FALSE; + } + + pSiS->HaveCustomModes = FALSE; + if(SiSMakeOwnModeList(pScrn, acceptcustommodes, includelcdmodes, isfordvi, &pSiS->HaveCustomModes)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Replaced %s mode list with built-in modes\n", + pSiS->HaveCustomModes ? "default" : "entire"); #ifdef TWDEBUG - pScrn->modes = pScrn->monitor->Modes; - xf86PrintModes(pScrn); - pScrn->modes = NULL; -#endif - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + pScrn->modes = pScrn->monitor->Modes; + xf86PrintModes(pScrn); + pScrn->modes = NULL; +#endif + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Building list of built-in modes failed, using XFree86 defaults\n"); - } - } + } + } else { + pSiS->HaveCustomModes = TRUE; + } } /* - * TW: Add our built-in modes for TV on the 6326 + * Add our built-in modes for TV on the 6326 */ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { - if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Adding %s TV modes for 6326 to mode list:\n", (pSiS->SiS6326Flags & SIS6326_TVPAL) ? "PAL" : "NTSC"); - if(pSiS->SiS6326Flags & SIS6326_TVPAL) { - SiS6326PAL800x600Mode.next = pScrn->monitor->Modes; - pScrn->monitor->Modes = &SiS6326PAL640x480Mode; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + if(pSiS->SiS6326Flags & SIS6326_TVPAL) { + SiS6326PAL800x600Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &SiS6326PAL640x480Mode; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\"PAL800x600\" \"PAL800x600U\" \"PAL720x540\" \"PAL640x480\"\n"); - } else { - SiS6326NTSC640x480Mode.next = pScrn->monitor->Modes; - pScrn->monitor->Modes = &SiS6326NTSC640x400Mode; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + } else { + SiS6326NTSC640x480Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &SiS6326NTSC640x400Mode; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\"NTSC640x480\" \"NTSC640x480U\" \"NTSC640x400\"\n"); - } - } + } + } } /* - * TW: Add our built-in hi-res modes on the 6326 + * Add our built-in hi-res modes on the 6326 */ if(pSiS->Chipset == PCI_CHIP_SIS6326) { if(pScrn->bitsPerPixel == 8) { @@ -3223,17 +4407,41 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* Select valid modes from those available */ /* - * Assuming min pitch 256, max 4096 ==> 8192 - * Assuming min height 128, max 4096 + * Assuming min pitch 256, min height 128 */ - i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, - pScrn->display->modes, clockRanges, - NULL, 256, 8192, - pScrn->bitsPerPixel * 8, 128, 4096, + { + int minpitch, maxpitch, minheight, maxheight; + minpitch = 256; + minheight = 128; + switch(pSiS->VGAEngine) { + case SIS_OLD_VGA: + case SIS_530_VGA: + maxpitch = 2040; + maxheight = 2048; + break; + case SIS_300_VGA: + case SIS_315_VGA: + maxpitch = 4088; + maxheight = 4096; + break; + default: + maxpitch = 2048; + maxheight = 2048; + break; + } +#ifdef SISMERGED + pSiS->CheckForCRT2 = FALSE; +#endif + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, NULL, + minpitch, maxpitch, + pScrn->bitsPerPixel * 8, + minheight, maxheight, pScrn->display->virtualX, pScrn->display->virtualY, pSiS->maxxfbmem, LOOKUP_BEST_REFRESH); + } if(i == -1) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -3247,11 +4455,30 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - /* TW: Go through mode list and mark all those modes as bad, - * - which are unsuitable for dual head mode (if running dhm), - * - which exceed the LCD panels specs (if running on LCD) - * - TODO: which exceed TV capabilities (if running on TV) - * Also, find the highest used pixelclock on the master head. + /* Check the virtual screen against the available memory */ + { + unsigned long memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8)) * pScrn->virtualY; + + if(memreq > pSiS->maxxfbmem) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Virtual screen too big for memory; %dK needed, %dK available\n", + memreq/1024, pSiS->maxxfbmem/1024); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + pSiS->pInt = NULL; + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); + SISFreeRec(pScrn); + return FALSE; + } + } + + /* Go through mode list and mark all those modes as bad, + * - which are unsuitable for dual head mode (if running dhm), + * - which exceed the LCD panels specs (if running on LCD) + * - TODO: which exceed TV capabilities (if running on TV) + * Also, find the highest used pixelclock on the master head. */ #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { @@ -3262,79 +4489,40 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) do { n = p->next; - /* TW: Check the modes if they comply with our built-in tables. - * This is of practical use only if the user disabled the - * usage of the internal (built-in) modes. - */ - if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { - if(p->type & M_T_DEFAULT) { - if( ( (strcmp(p->name, "320x200") != 0) && - (strcmp(p->name, "320x240") != 0) && - (strcmp(p->name, "400x300") != 0) && - (strcmp(p->name, "512x384") != 0) ) && - (p->Flags & V_DBLSCAN) ) { - p->status = MODE_NO_DBLESCAN; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using mode \"%s\" (mode not supported as doublescan)\n", p->name); - } - if( ( (strcmp(p->name, "1024x768") != 0) && - (strcmp(p->name, "1280x1024") != 0) && - (strcmp(p->name, "848x480") != 0) && - (strcmp(p->name, "856x480") != 0)) && - (p->Flags & V_INTERLACE) ) { - p->status = MODE_NO_INTERLACE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using mode \"%s\" (mode not supported as interlaced)\n", p->name); - } - if( ( (strcmp(p->name, "320x200") == 0) || - (strcmp(p->name, "320x240") == 0) || - (strcmp(p->name, "400x300") == 0) || - (strcmp(p->name, "512x384") == 0) ) && - (!(p->Flags & V_DBLSCAN)) ) { - p->status = MODE_CLOCK_RANGE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using mode \"%s\" (only supported as doublescan)\n", p->name); - } - } - } #ifdef SISDUALHEAD - /* TW: Modes that require the bridge to operate in SlaveMode - * are not suitable for Dual Head mode. Also check for - * modes that exceed panel dimension. + /* Modes that require the bridge to operate in SlaveMode + * are not suitable for Dual Head mode. Also check for + * modes that exceed panel dimension. */ if(pSiS->DualHeadMode) { if(pSiS->SecondHead == FALSE) { - if( (strcmp(p->name, "320x200") == 0) || - (strcmp(p->name, "320x240") == 0) || - (strcmp(p->name, "400x300") == 0) || - (strcmp(p->name, "512x384") == 0) || - (strcmp(p->name, "640x400") == 0) ) { + if( pSiS->VGAEngine == SIS_300_VGA && + ( (strcmp(p->name, "320x200") == 0) || + (strcmp(p->name, "320x240") == 0) || + (strcmp(p->name, "400x300") == 0) || + (strcmp(p->name, "512x384") == 0) || + (strcmp(p->name, "640x400") == 0) ) ) { p->status = MODE_BAD; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" (not suitable for dual head mode)\n", p->name); } - } - if(pSiS->VBFlags & DISPTYPE_DISP2) { - if(pSiS->VBFlags & CRT2_LCD) { - if(pSiS->SecondHead == FALSE) { + if(p->Flags & V_INTERLACE) { + p->status = MODE_BAD; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (interlace not supported on CRT2)\n", + p->name); + } + if((pSiS->VBFlags & CRT2_LCD) && (pSiS->SiS_Pr->SiS_CustomT != CUT_PANEL848)) { if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) { p->status = MODE_PANEL; xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name); + "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name); } - if(p->Flags & V_INTERLACE) { - p->status = MODE_BAD; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using mode \"%s\" (interlace on LCD not supported)\n", - p->name); - } - } - } - /* TO DO: TV */ + } } - /* TW: Search for the highest clock on first head in order to calculate - * max clock for second head (CRT1) + /* Search for the highest clock on first head in order to calculate + * max clock for second head (CRT1) */ if(!pSiS->SecondHead) { if((p->status == MODE_OK) && (p->Clock > pSiSEnt->maxUsedClock)) { @@ -3344,19 +4532,24 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } else { #endif if(pSiS->VBFlags & DISPTYPE_DISP2) { - if(pSiS->VBFlags & CRT2_LCD) { - if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) { - p->status = MODE_PANEL; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name); - } - if(p->Flags & V_INTERLACE) { - p->status = MODE_BAD; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using mode \"%s\" (interlace on LCD not supported)\n", - p->name); - } - } +#ifdef SISMERGED + if(!pSiS->MergedFB) { +#endif + if((pSiS->VBFlags & CRT2_LCD) && (pSiS->SiS_Pr->SiS_CustomT != CUT_PANEL848)) { + if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) { + p->status = MODE_PANEL; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name); + } + } + if(p->Flags & V_INTERLACE) { + p->status = MODE_BAD; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (interlace not supported on CRT2)\n", p->name); + } +#ifdef SISMERGED + } +#endif } #ifdef SISDUALHEAD } @@ -3388,24 +4581,224 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->CurrentLayout.mode = pScrn->currentMode; pSiS->CurrentLayout.displayWidth = pScrn->displayWidth; +#ifdef SISMERGED + if(pSiS->MergedFB) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Modes for CRT1: *********************************************\n"); + } +#endif + /* Print the list of modes being used */ xf86PrintModes(pScrn); -#ifdef SISDUALHEAD - /* TW: Due to palette & timing problems we don't support 8bpp in DHM */ - if((pSiS->DualHeadMode) && (pScrn->bitsPerPixel == 8)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Colordepth 8 not supported in Dual Head mode.\n"); - if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; - if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); - sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); - SISFreeRec(pScrn); - return FALSE; +#ifdef SISMERGED + if(pSiS->MergedFB) { + BOOLEAN acceptcustommodes = TRUE; + BOOLEAN includelcdmodes = TRUE; + BOOLEAN isfordvi = FALSE; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "------------------------ CRT2 setup -------------------------\n"); + clockRanges->next = NULL; + clockRanges->minClock = pSiS->MinClock; + clockRanges->maxClock = SiSMemBandWidth(pSiS->CRT2pScrn, TRUE); + clockRanges->clockIndex = -1; + clockRanges->interlaceAllowed = FALSE; + clockRanges->doubleScanAllowed = FALSE; + if(pSiS->VGAEngine == SIS_315_VGA) { + clockRanges->doubleScanAllowed = TRUE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock for CRT2 is %d MHz\n", + clockRanges->minClock / 1000); + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Max pixel clock for CRT2 is %d MHz\n", + clockRanges->maxClock / 1000); + + if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B)) { + if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; + if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; + if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE; + } else { + includelcdmodes = FALSE; + acceptcustommodes = FALSE; + } + + pSiS->HaveCustomModes2 = FALSE; + if(!SiSMakeOwnModeList(pSiS->CRT2pScrn, acceptcustommodes, includelcdmodes, isfordvi, &pSiS->HaveCustomModes2)) { + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Building list of built-in modes for CRT2 failed, MergedFB mode disabled\n"); + if(pSiS->CRT2pScrn) { + if(pSiS->CRT2pScrn->monitor) { + if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC); + xfree(pSiS->CRT2pScrn->monitor); + } + xfree(pSiS->CRT2pScrn); + } + pSiS->CRT2pScrn = NULL; + pSiS->MergedFB = FALSE; + + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Replaced %s mode list for CRT2 with built-in modes\n", + pSiS->HaveCustomModes2 ? "default" : "entire"); + } + + } + + if(pSiS->MergedFB) { + + pSiS->CheckForCRT2 = TRUE; + i = xf86ValidateModes(pSiS->CRT2pScrn, pSiS->CRT2pScrn->monitor->Modes, + pSiS->CRT2pScrn->display->modes, clockRanges, + NULL, 256, 4088, + pSiS->CRT2pScrn->bitsPerPixel * 8, 128, 4096, + pScrn->virtualX, /* pSiS->CRT2pScrn->display->virtualX, */ + pScrn->virtualY, /* pSiS->CRT2pScrn->display->virtualY, */ + pSiS->maxxfbmem, + LOOKUP_BEST_REFRESH); + pSiS->CheckForCRT2 = FALSE; + + if(i == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86ValidateModes() error, MergedFB mode disabled.\n"); + if(pSiS->CRT2pScrn) { + if(pSiS->CRT2pScrn->modes) { + while(pSiS->CRT2pScrn->modes) + xf86DeleteMode(&pSiS->CRT2pScrn->modes, pSiS->CRT2pScrn->modes); + } + if(pSiS->CRT2pScrn->monitor) { + if(pSiS->CRT2pScrn->monitor->Modes) { + while(pSiS->CRT2pScrn->monitor->Modes) + xf86DeleteMode(&pSiS->CRT2pScrn->monitor->Modes, pSiS->CRT2pScrn->monitor->Modes); + } + if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC); + xfree(pSiS->CRT2pScrn->monitor); + } + xfree(pSiS->CRT2pScrn); + } + pSiS->CRT2pScrn = NULL; + pSiS->MergedFB = FALSE; + } + + } + + if(pSiS->MergedFB) { + + if((p = first = pSiS->CRT2pScrn->modes)) { + do { + n = p->next; + if( pSiS->VGAEngine == SIS_300_VGA && + ( (strcmp(p->name, "320x200") == 0) || + (strcmp(p->name, "320x240") == 0) || + (strcmp(p->name, "400x300") == 0) || + (strcmp(p->name, "512x384") == 0) || + (strcmp(p->name, "640x400") == 0) ) ) { + p->status = MODE_BAD; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (not suitable for MergedFB mode)\n", + p->name); + } + if((pSiS->VBFlags & CRT2_LCD) && (pSiS->SiS_Pr->SiS_CustomT != CUT_PANEL848)) { + if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) { + p->status = MODE_PANEL; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name); + } + } + } while (p != NULL && p != first); + } + + xf86PruneDriverModes(pSiS->CRT2pScrn); + + if(i == 0 || pSiS->CRT2pScrn->modes == NULL) { + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid modes found for CRT2; MergedFB mode disabled\n"); + if(pSiS->CRT2pScrn) { + if(pSiS->CRT2pScrn->modes) { + while(pSiS->CRT2pScrn->modes) + xf86DeleteMode(&pSiS->CRT2pScrn->modes, pSiS->CRT2pScrn->modes); + } + if(pSiS->CRT2pScrn->monitor) { + if(pSiS->CRT2pScrn->monitor->Modes) { + while(pSiS->CRT2pScrn->monitor->Modes) + xf86DeleteMode(&pSiS->CRT2pScrn->monitor->Modes, pSiS->CRT2pScrn->monitor->Modes); + } + if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC); + xfree(pSiS->CRT2pScrn->monitor); + } + xfree(pSiS->CRT2pScrn); + } + pSiS->CRT2pScrn = NULL; + pSiS->MergedFB = FALSE; + + } + + } + + if(pSiS->MergedFB) { + + xf86SetCrtcForModes(pSiS->CRT2pScrn, INTERLACE_HALVE_V); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Modes for CRT2: *********************************************\n"); + + xf86PrintModes(pSiS->CRT2pScrn); + + pSiS->CRT1Modes = pScrn->modes; + pSiS->CRT1CurrentMode = pScrn->currentMode; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Generating MergedFB mode list\n"); + + pScrn->modes = SiSGenerateModeList(pScrn, pSiS->MetaModes, + pSiS->CRT1Modes, pSiS->CRT2pScrn->modes, + pSiS->CRT2Position); + + if(!pScrn->modes) { + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to parse MetaModes or no modes found. MergedFB mode disabled.\n"); + if(pSiS->CRT2pScrn) { + if(pSiS->CRT2pScrn->modes) { + while(pSiS->CRT2pScrn->modes) + xf86DeleteMode(&pSiS->CRT2pScrn->modes, pSiS->CRT2pScrn->modes); + } + if(pSiS->CRT2pScrn->monitor) { + if(pSiS->CRT2pScrn->monitor->Modes) { + while(pSiS->CRT2pScrn->monitor->Modes) + xf86DeleteMode(&pSiS->CRT2pScrn->monitor->Modes, pSiS->CRT2pScrn->monitor->Modes); + } + if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC); + xfree(pSiS->CRT2pScrn->monitor); + } + xfree(pSiS->CRT2pScrn); + } + pScrn->modes = pSiS->CRT1Modes; + pSiS->CRT1Modes = NULL; + pSiS->MergedFB = FALSE; + + } else { + + pScrn->modes = pScrn->modes->next; + pScrn->currentMode = pScrn->modes; + + /* Update CurrentLayout */ + pSiS->CurrentLayout.mode = pScrn->currentMode; + pSiS->CurrentLayout.displayWidth = pScrn->displayWidth; + + } + } #endif /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); +#ifdef SISMERGED + if(pSiS->MergedFB) { + xf86SetDpi(pSiS->CRT2pScrn, 0, 0); + } +#endif /* Load bpp-specific modules */ switch(pScrn->bitsPerPixel) { @@ -3478,8 +4871,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(shadowSymbols, NULL); } - - /* TW: Now load and initialize VBE module for VESA. */ + /* Now load and initialize VBE module for VESA and mode restoring. */ pSiS->UseVESA = 0; if(pSiS->VESA == 1) { if(!pSiS->pVbe) { @@ -3489,24 +4881,27 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->pVbe = VBEInit(pSiS->pInt,pSiS->pEnt->index); #else pSiS->pVbe = VBEExtendedInit(pSiS->pInt,pSiS->pEnt->index, - SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); + SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); #endif } } if(pSiS->pVbe) { - vbe = VBEGetVBEInfo(pSiS->pVbe); - pSiS->vesamajor = (unsigned)(vbe->VESAVersion >> 8); - pSiS->vesaminor = vbe->VESAVersion & 0xff; - pSiS->vbeInfo = vbe; - SiSBuildVesaModeList(pScrn, pSiS->pVbe, vbe); - VBEFreeVBEInfo(vbe); - pSiS->UseVESA = 1; + vbe = VBEGetVBEInfo(pSiS->pVbe); + pSiS->vesamajor = (unsigned)(vbe->VESAVersion >> 8); + pSiS->vesaminor = vbe->VESAVersion & 0xff; + pSiS->vbeInfo = vbe; + if(pSiS->VESA == 1) { + SiSBuildVesaModeList(pScrn, pSiS->pVbe, vbe); + VBEFreeVBEInfo(vbe); + pSiS->UseVESA = 1; + } } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Could not load and initialize VBE module. VESA disabled.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not load and initialize VBE module.%s\n", + (pSiS->VESA == 1) ? " VESA disabled." : ""); } - } - + } + if(pSiS->pVbe) { vbeFree(pSiS->pVbe); pSiS->pVbe = NULL; @@ -3521,6 +4916,21 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); pSiS->pInt = NULL; +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiS->SiS_SD_Flags |= SiS_SD_ISDUALHEAD; + if(pSiS->SecondHead) pSiS->SiS_SD_Flags |= SiS_SD_ISDHSECONDHEAD; + if(!noPanoramiXExtension) pSiS->SiS_SD_Flags |= SiS_SD_ISDHXINERAMA; + } +#endif +#ifdef SISMERGED + if(pSiS->MergedFB) pSiS->SiS_SD_Flags |= SiS_SD_ISMERGEDFB; +#endif + + if(pSiS->enablesisctrl) pSiS->SiS_SD_Flags |= SiS_SD_ENABLED; + + if(pSiS->CurrentLayout.bitsPerPixel == 8) pSiS->SiS_SD_Flags |= SiS_SD_ISDEPTH8; + return TRUE; } @@ -3560,7 +4970,7 @@ SISMapMem(ScrnInfoPtr pScrn) if(pSiS->DualHeadMode) { pSiSEnt->MapCountIOBase++; if(!(pSiSEnt->IOBase)) { - /* TW: Only map if not mapped previously */ + /* Only map if not mapped previously */ pSiSEnt->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pSiS->PciTag, pSiS->IOAddress, 0x10000); } @@ -3585,7 +4995,7 @@ SISMapMem(ScrnInfoPtr pScrn) if(pSiS->DualHeadMode) { pSiSEnt->MapCountIOBaseDense++; if(!(pSiSEnt->IOBaseDense)) { - /* TW: Only map if not mapped previously */ + /* Only map if not mapped previously */ pSiSEnt->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSiS->PciTag, pSiS->IOAddress, 0x10000); } @@ -3607,14 +5017,14 @@ SISMapMem(ScrnInfoPtr pScrn) if(pSiS->DualHeadMode) { pSiSEnt->MapCountFbBase++; if(!(pSiSEnt->FbBase)) { - /* TW: Only map if not mapped previously */ + /* Only map if not mapped previously */ pSiSEnt->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, pSiS->PciTag, (unsigned long)pSiS->realFbAddress, pSiS->FbMapSize); pSiS->sishw_ext.pjVideoMemoryAddress = (UCHAR *)pSiSEnt->FbBase; } pSiS->FbBase = pSiSEnt->FbBase; - /* TW: Adapt FbBase (for DHM; dhmOffset is 0 otherwise) */ + /* Adapt FbBase (for DHM; dhmOffset is 0 otherwise) */ pSiS->FbBase += pSiS->dhmOffset; } else { #endif @@ -3654,9 +5064,9 @@ SISUnmapMem(ScrnInfoPtr pScrn) pSiSEnt = pSiS->entityPrivate; #endif -/* TW: In dual head mode, we must not unmap if the other head still - * assumes memory as mapped -*/ +/* In dual head mode, we must not unmap if the other head still + * assumes memory as mapped + */ #ifdef SISDUALHEAD if (pSiS->DualHeadMode) { if (pSiSEnt->MapCountIOBase) { @@ -3721,14 +5131,28 @@ SISSave(ScrnInfoPtr pScrn) pSiS = SISPTR(pScrn); #ifdef SISDUALHEAD - /* TW: We always save master & slave */ + /* We always save master & slave */ if(pSiS->DualHeadMode && pSiS->SecondHead) return; #endif vgaReg = &VGAHWPTR(pScrn)->SavedReg; sisReg = &pSiS->SavedReg; - vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (SiSBridgeIsInSlaveMode(pScrn))) { + vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE); + SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30); + SiSSetLVDSetc(pSiS->SiS_Pr, &pSiS->sishw_ext, 0); + SiS_GetVBType(pSiS->SiS_Pr, pSiS->RelIO+0x30, &pSiS->sishw_ext); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + } else { + vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); + } + } else { + vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); + } sisSaveUnlockExtRegisterLock(pSiS,&sisReg->sisRegs3C4[0x05],&sisReg->sisRegs3D4[0x80]); @@ -3736,16 +5160,20 @@ SISSave(ScrnInfoPtr pScrn) if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_SAVE); - /* TW: Save these as they may have been changed prior to SISSave() call */ + /* Save these as they may have been changed prior to SISSave() call */ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { sisReg->sisRegs3D4[0x17] = pSiS->oldCR17; if(vgaReg->numCRTC >= 0x17) vgaReg->CRTC[0x17] = pSiS->oldCR17; sisReg->sisRegs3D4[0x32] = pSiS->oldCR32; + sisReg->sisRegs3C4[0x1f] = pSiS->oldSR1F; + if(pSiS->VGAEngine == SIS_315_VGA) { + sisReg->sisRegs3D4[0x63] = pSiS->oldCR63; + } } } /* - * TW: Just adapted from the std* functions in vgaHW.c + * Just adapted from the std* functions in vgaHW.c */ static void SiS_WriteAttr(SISPtr pSiS, int index, int value) @@ -3771,7 +5199,6 @@ SiS_ReadAttr(SISPtr pSiS, int index) return (inb(pSiS->IODBase + VGA_ATTR_DATA_R)); } - static void SiS_SaveFonts(ScrnInfoPtr pScrn) { @@ -3919,7 +5346,7 @@ SiS_RestoreFonts(ScrnInfoPtr pScrn) outSISIDXREG(SISSR, 0x04, seq4); } -/* TW: VESASaveRestore taken from vesa driver */ +/* VESASaveRestore taken from vesa driver */ static void SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) { @@ -3966,46 +5393,15 @@ SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL); SiS_RestoreFonts(pScrn); } -#if 0 - if (!retval) - return (FALSE); -#endif } -#if 0 - if ( (pSiS->vesamajor > 1) && - (function == MODE_SAVE || pSiS->pstate) ) { - if (function == MODE_RESTORE) - memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize); - if ((VBESaveRestore(pSiS->pVbe,function, - (pointer)&pSiS->state, - &pSiS->stateSize,&pSiS->statePage))) { - if (function == MODE_SAVE) { - /* don't rely on the memory not being touched */ - if (pSiS->pstate == NULL) - pSiS->pstate = xalloc(pSiS->stateSize); - memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize); - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "VBESaveRestore done with success\n"); - return; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "VBESaveRestore done\n"); - } else { - if (function == MODE_SAVE) - (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode); - else - VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL); - } -#endif } /* * Initialise a new mode. This is currently done using the * "initialise struct, restore/write struct to HW" model for * the old chipsets (5597/530/6326). For newer chipsets, - * we use either VESA or our own mode switching code. + * we use our own mode switching code (or VESA). */ static Bool @@ -4015,27 +5411,29 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) vgaRegPtr vgaReg; SISPtr pSiS = SISPTR(pScrn); SISRegPtr sisReg; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = NULL; +#endif - vgaHWUnlock(hwp); + andSISIDXREG(SISCR,0x11,0x7f); /* Unlock CRTC registers */ - SISModifyModeInfo(mode); + SISModifyModeInfo(mode); /* Quick check of the mode parameters */ - /* TW: Initialize SiS Port Register definitions for externally used - * BIOS emulation (native code switching) functions. - */ - if( pSiS->VGAEngine == SIS_300_VGA || - pSiS->VGAEngine == SIS_315_VGA ) { + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30); } - if (pSiS->UseVESA) { /* With VESA: */ + if(pSiS->UseVESA) { /* With VESA: */ #ifdef SISDUALHEAD - /* TW: No dual head mode when using VESA */ - if (pSiS->SecondHead) return TRUE; + /* No dual head mode when using VESA */ + if(pSiS->SecondHead) return TRUE; #endif + + pScrn->vtSema = TRUE; + /* - * TW: This order is required: + * This order is required: * The video bridge needs to be adjusted before the * BIOS is run as the BIOS sets up CRT2 according to * these register settings. @@ -4043,66 +5441,62 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) * registers need to be readjusted as the BIOS may * very probably have messed them up. */ - if( pSiS->VGAEngine == SIS_300_VGA || - pSiS->VGAEngine == SIS_315_VGA ) { - SiSPreSetMode(pScrn, mode); + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + SiSPreSetMode(pScrn, mode); } if(!SiSSetVESAMode(pScrn, mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "SiSSetVESAMode() failed\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "SiSSetVESAMode() failed\n"); + return FALSE; } sisSaveUnlockExtRegisterLock(pSiS,NULL,NULL); - if( pSiS->VGAEngine == SIS_300_VGA || - pSiS->VGAEngine == SIS_315_VGA ) { - SiSPreSetMode(pScrn, mode); - SiSPostSetMode(pScrn, &pSiS->ModeReg); + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + SiSPreSetMode(pScrn, mode); + SiSPostSetMode(pScrn, &pSiS->ModeReg); } - /* TW: Prepare some register contents and set - * up some mode dependent variables. + /* Prepare some register contents and set + * up some mode dependent variables. */ #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "REAL REGISTER CONTENTS AFTER SETMODE:\n"); + "REAL REGISTER CONTENTS AFTER SETMODE:\n"); #endif - if (!(*pSiS->ModeInit)(pScrn, mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "ModeInit() failed\n"); - return FALSE; + if(!(*pSiS->ModeInit)(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ModeInit() failed\n"); + return FALSE; } - pScrn->vtSema = TRUE; - /* Program the registers */ vgaHWProtect(pScrn, TRUE); (*pSiS->SiSRestore)(pScrn, &pSiS->ModeReg); vgaHWProtect(pScrn, FALSE); - PDEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "HDisplay: %d, VDisplay: %d \n", - mode->HDisplay, mode->VDisplay)); } else { /* Without VESA: */ + #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { if(!(*pSiS->ModeInit)(pScrn, mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "ModeInit() failed\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ModeInit() failed\n"); return FALSE; } pScrn->vtSema = TRUE; + pSiSEnt = pSiS->entityPrivate; + if(!(pSiS->SecondHead)) { - /* TW: Head 1 (master) is always CRT2 */ + /* Head 1 (master) is always CRT2 */ SiSPreSetMode(pScrn, mode); - if (!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode)) { + if (!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "SiSBIOSSetModeCRT2() failed\n"); return FALSE; } SiSPostSetMode(pScrn, &pSiS->ModeReg); + SISAdjustFrame(pSiSEnt->pScrn_2->scrnIndex, + pSiSEnt->pScrn_2->frameX0, + pSiSEnt->pScrn_2->frameY0, 0); } else { - /* TW: Head 2 (slave) is always CRT1 */ + /* Head 2 (slave) is always CRT1 */ SiSPreSetMode(pScrn, mode); if (!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -4110,37 +5504,56 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) return FALSE; } SiSPostSetMode(pScrn, &pSiS->ModeReg); + SISAdjustFrame(pSiSEnt->pScrn_1->scrnIndex, + pSiSEnt->pScrn_1->frameX0, + pSiSEnt->pScrn_1->frameY0, 0); } } else { #endif - if(pSiS->VGAEngine == SIS_300_VGA || - pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { - /* TW: Prepare the register contents; On 300/310/325, - * we actually "abuse" this only for setting - * up some variables; the registers are NOT - * being written to the hardware as the BIOS - * emulation (native mode switching code) - * takes care of this. - */ + /* Set up some mode-depending variables */ if(!(*pSiS->ModeInit)(pScrn, mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "ModeInit() failed\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ModeInit() failed\n"); return FALSE; } pScrn->vtSema = TRUE; - /* 300/310/325 series: Use our own code for mode switching */ SiSPreSetMode(pScrn, mode); - if(!SiSBIOSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { +#ifdef SISMERGED + if(pSiS->MergedFB) { + + xf86DrvMsg(0, X_INFO, "Setting MergedFB mode %dx%d\n", + mode->HDisplay, mode->VDisplay); + + if(!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, + ((SiSMergedDisplayModePtr)mode->Private)->CRT1, + pSiS->IsCustom)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSBIOSSetModeCRT1() failed\n"); + return FALSE; + } + if(!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, + ((SiSMergedDisplayModePtr)mode->Private)->CRT2, + pSiS->IsCustomCRT2)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSBIOSSetModeCRT2() failed\n"); + return FALSE; + } + + } else +#endif + if(!SiSBIOSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, + mode, pSiS->IsCustom)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "SiSBIOSSetMode() failed\n"); return FALSE; } SiSPostSetMode(pScrn, &pSiS->ModeReg); + #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, "REAL REGISTER CONTENTS AFTER SETMODE:\n"); @@ -4152,9 +5565,8 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) /* Initialise the ModeReg values */ if(!vgaHWInit(pScrn, mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "vgaHWInit() failed\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "vgaHWInit() failed\n"); + return FALSE; } /* Reset our PIOOffset as vgaHWInit might have reset it */ @@ -4162,9 +5574,8 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) /* Prepare the register contents */ if(!(*pSiS->ModeInit)(pScrn, mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "ModeInit() failed\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ModeInit() failed\n"); + return FALSE; } pScrn->vtSema = TRUE; @@ -4176,7 +5587,7 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) vgaReg->Attribute[0x10] = 0x01; if(pScrn->bitsPerPixel > 8) { - vgaReg->Graphics[0x05] = 0x00; + vgaReg->Graphics[0x05] = 0x00; } vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); @@ -4184,7 +5595,7 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) (*pSiS->SiSRestore)(pScrn, sisReg); if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { - SiS6326PostSetMode(pScrn, &pSiS->ModeReg); + SiS6326PostSetMode(pScrn, &pSiS->ModeReg); } #ifdef TWDEBUG @@ -4200,12 +5611,9 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) #endif } - /* TW: Update Currentlayout */ + /* Update Currentlayout */ pSiS->CurrentLayout.mode = mode; - /* Debug */ -/* SiSDumpModeInfo(pScrn, mode); */ - return TRUE; } @@ -4219,8 +5627,8 @@ SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) if (!(mode = SiSCalcVESAModeIndex(pScrn, pMode))) return FALSE; - mode |= 1 << 15; /* TW: Don't clear framebuffer */ - mode |= 1 << 14; /* TW: Use linear adressing */ + mode |= 1 << 15; /* Don't clear framebuffer */ + mode |= 1 << 14; /* Use linear adressing */ if(VBESetVBEMode(pSiS->pVbe, mode, NULL) == FALSE) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -4239,6 +5647,72 @@ SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) return (TRUE); } +static void +SISSpecialRestore(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + SISRegPtr sisReg = &pSiS->SavedReg; + unsigned char temp; + int i; + + /* 1.11.04 and later for 651 and 301B(DH) do strange register + * fiddling after the usual mode change. This happens + * depending on the result of a call of int 2f (with + * ax=0x1680) and if modeno <= 0x13. I have no idea if + * that is specific for the 651 or that very machine. + * So this perhaps requires some more checks in the beginning + * (although it should not do any harm on other chipsets/bridges + * etc.) However, even if I call the VBE to restore mode 0x03, + * these registers don't get restored correctly, possibly + * because that int-2f-call results non-zero. So + * what I do here is to restore these few registers + * manually. + */ + + if(!(pSiS->ChipFlags & SiSCF_Is65x)) return; + inSISIDXREG(SISCR, 0x34, temp); + if(temp > 0x13) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL); +#endif + + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + + outSISIDXREG(SISCAP, 0x3f, sisReg->sisCapt[0x3f]); + outSISIDXREG(SISCAP, 0x00, sisReg->sisCapt[0x00]); + for(i = 0; i < 0x4f; i++) { + outSISIDXREG(SISCAP, i, sisReg->sisCapt[i]); + } + outSISIDXREG(SISVID, 0x32, (sisReg->sisVid[0x32] & ~0x05)); + outSISIDXREG(SISVID, 0x30, sisReg->sisVid[0x30]); + outSISIDXREG(SISVID, 0x32, ((sisReg->sisVid[0x32] & ~0x04) | 0x01)); + outSISIDXREG(SISVID, 0x30, sisReg->sisVid[0x30]); + + if(!(pSiS->ChipFlags & SiSCF_Is651)) return; + if(!(pSiS->VBFlags & VB_SISBRIDGE)) return; + + inSISIDXREG(SISCR, 0x30, temp); + if(temp & 0x40) { + unsigned char myregs[] = { + 0x2f, 0x08, 0x09, 0x03, 0x0a, 0x0c, + 0x0b, 0x0d, 0x0e, 0x12, 0x0f, 0x10, + 0x11, 0x04, 0x05, 0x06, 0x07, 0x00, + 0x2e + }; + for(i = 0; i <= 18; i++) { + outSISIDXREG(SISPART1, myregs[i], sisReg->VBPart1[myregs[i]]); + } + } else if((temp & 0x20) || (temp & 0x9c)) { + unsigned char myregs[] = { + 0x04, 0x05, 0x06, 0x07, 0x00, 0x2e + }; + for(i = 0; i <= 5; i++) { + outSISIDXREG(SISPART1, myregs[i], sisReg->VBPart1[myregs[i]]); + } + } +} + /* * Restore the initial mode. To be used internally only! */ @@ -4250,15 +5724,26 @@ SISRestore(ScrnInfoPtr pScrn) vgaHWPtr hwp = VGAHWPTR(pScrn); vgaRegPtr vgaReg = &hwp->SavedReg; Bool doit = FALSE, doitlater = FALSE; + Bool vesasuccess = FALSE; + + /* WARNING: Don't ever touch this. It now seems to work on + * all chipset/bridge combinations - but finding out the + * correct combination was pure hell. + */ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { #ifdef SISDUALHEAD - /* TW: We always restore master AND slave */ + /* We always restore master AND slave */ if(pSiS->DualHeadMode && pSiS->SecondHead) return; #endif - /* TW: We must not disable the sequencer if the bridge is in SlaveMode! */ + /* Wait for the accelerators */ + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + + /* We must not disable the sequencer if the bridge is in SlaveMode! */ if(!(SiSBridgeIsInSlaveMode(pScrn))) { vgaHWProtect(pScrn, TRUE); } @@ -4267,66 +5752,98 @@ SISRestore(ScrnInfoPtr pScrn) sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL); #endif - /* TW: First, restore CRT1 on/off and VB connection registers */ + /* First, restore CRT1 on/off and VB connection registers */ outSISIDXREG(SISCR, 0x32, pSiS->oldCR32); - if(!(pSiS->oldCR17 & 0x80)) { /* TW: CRT1 was off */ - if(!(SiSBridgeIsInSlaveMode(pScrn))) { /* TW: Bridge is NOT in SlaveMode now -> do it */ + if(!(pSiS->oldCR17 & 0x80)) { /* CRT1 was off */ + if(!(SiSBridgeIsInSlaveMode(pScrn))) { /* Bridge is NOT in SlaveMode now -> do it */ doit = TRUE; } else { doitlater = TRUE; } - } else { /* TW: CRT1 was on -> do it now */ + } else { /* CRT1 was on -> do it now */ doit = TRUE; } if(doit) { - outSISIDXREG(SISCR, 0x17, pSiS->oldCR17); + outSISIDXREG(SISCR, 0x17, pSiS->oldCR17); + } + if(pSiS->VGAEngine == SIS_315_VGA) { + outSISIDXREG(SISCR, 0x63, pSiS->oldCR63); } - /* TW: For 30xB/LV, restoring the registers does not - * work. We "manually" set the old mode, instead. - * The same applies for SiS730 machines with LVDS. - * Finally, this behavior can be forced by setting - * the option RestoreBySetMode. + outSISIDXREG(SISSR, 0x1f, pSiS->oldSR1F); + + /* For 30xB/LV, restoring the registers does not + * work. We "manually" set the old mode, instead. + * The same applies for SiS730 machines with LVDS. + * Finally, this behavior can be forced by setting + * the option RestoreBySetMode. */ if( ( (pSiS->restorebyset) || - (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) || + (pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) || ((pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ) && (pSiS->OldMode) ) { - if(pSiS->AccelInfoPtr) { - (*pSiS->AccelInfoPtr->Sync)(pScrn); - } - + Bool changedmode = FALSE; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Restoring by setting old mode 0x%02x\n", pSiS->OldMode); + + if((pSiS->OldMode <= 0x13) && (pSiS->pVbe)) { + if(VBESetVBEMode(pSiS->pVbe, pSiS->OldMode, NULL) == TRUE) { + SISSpecialRestore(pScrn); + SiS_GetSetModeID(pScrn,pSiS->OldMode); + vesasuccess = TRUE; + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "VBE failed to restore mode 0x%x\n", pSiS->OldMode); + } + } + + if(vesasuccess == FALSE) { + + int backupscaler = pSiS->SiS_Pr->UsePanelScaler; + unsigned long backupspecialtiming = pSiS->SiS_Pr->SiS_CustomT; + + if((pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV))) { + /* !!! REQUIRED for 630+301B-DH, otherwise the text modes + * will not be restored correctly !!! + * !!! Do this ONLY for LCD; VGA2 will not be restored + * correctly otherwise. + */ + unsigned char temp; + inSISIDXREG(SISCR, 0x30, temp); + if(temp & 0x20) { + if(pSiS->OldMode == 0x03) { + pSiS->OldMode = 0x13; + changedmode = TRUE; + } + } + } + + pSiS->SiS_Pr->UseCustomMode = FALSE; + pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE; + pSiS->SiS_Pr->UsePanelScaler = pSiS->sisfbscalelcd; + pSiS->SiS_Pr->SiS_CustomT = pSiS->sisfbspecialtiming; + SiSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, pSiS->OldMode, FALSE); + if(changedmode) { + pSiS->OldMode = 0x03; + outSISIDXREG(SISCR,0x34,0x03); + } + SISSpecialRestore(pScrn); + SiS_GetSetModeID(pScrn,pSiS->OldMode); + pSiS->SiS_Pr->UsePanelScaler = backupscaler; + pSiS->SiS_Pr->SiS_CustomT = backupspecialtiming; - if( (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) && - (!pSiS->restorebyset) ) { - if(pSiS->OldMode == 0x03) pSiS->OldMode = 0x13; } - - pSiS->SiS_Pr->UseCustomMode = FALSE; - pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE; - SiSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, pSiS->OldMode, FALSE); -#ifdef TWDEBUG - { - SISRegPtr pReg = &pSiS->ModeReg; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "REAL REGISTER CONTENTS AFTER RESTORE BY SETMODE:\n"); - (*pSiS->SiSSave)(pScrn, pReg); - } -#endif } else { if(pSiS->VBFlags & VB_VIDEOBRIDGE) { - /* TW: If a video bridge is present, we need to restore - * non-extended (=standard VGA) SR and CR registers - * before restoring the extended ones and the bridge - * registers itself. Unfortunately, the vgaHWRestore - * routine clears CR17[7] - which must not be done if - * the bridge is in slave mode. + /* If a video bridge is present, we need to restore + * non-extended (=standard VGA) SR and CR registers + * before restoring the extended ones and the bridge + * registers itself. */ if(!(SiSBridgeIsInSlaveMode(pScrn))) { vgaHWProtect(pScrn, TRUE); @@ -4345,41 +5862,74 @@ SISRestore(ScrnInfoPtr pScrn) outSISIDXREG(SISCR, 0x17, pSiS->oldCR17); } - sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[0x05],sisReg->sisRegs3D4[0x80]); - - if( ( (pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) || - (pSiS->restorebyset) ) { - - /* TW: SiS730/LVDS has extreme problems restoring the text display due - * to over-sensible LCD panels - */ - - vgaHWProtect(pScrn, TRUE); - - if(pSiS->Primary) { - vgaHWRestore(pScrn, vgaReg, (VGA_SR_FONTS | VGA_SR_CMAP)); - } - - vgaHWProtect(pScrn, FALSE); - - } else { - - vgaHWProtect(pScrn, TRUE); - - if(pSiS->Primary) { + if(pSiS->Primary) { + if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (SiSBridgeIsInSlaveMode(pScrn))) { + /* IMPORTANT: The 30xLV does not handle well being disabled if in + * LCDA mode! In LCDA mode, the bridge is NOT in slave mode, + * so this is the only safe way: Disable the bridge ONLY if + * in Slave Mode, and don't bother if not. + */ + SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30); + SiSSetLVDSetc(pSiS->SiS_Pr, &pSiS->sishw_ext, 0); + SiS_GetVBType(pSiS->SiS_Pr, pSiS->RelIO+0x30, &pSiS->sishw_ext); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + + vgaHWProtect(pScrn, TRUE); + + /* We now restore ALL to overcome the vga=extended problem */ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + +#if 0 + if(pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) { + if(vesasuccess) { + vgaHWRestore(pScrn, vgaReg, (VGA_SR_CMAP | VGA_SR_FONTS)); + } else { + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + } + } else { + vgaHWRestore(pScrn, vgaReg, (VGA_SR_CMAP | VGA_SR_FONTS)); + } +#endif + + vgaHWProtect(pScrn, FALSE); + + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + andSISIDXREG(SISSR, 0x01, ~0x20); /* Display on */ + } else { + vgaHWProtect(pScrn, TRUE); + + /* We now restore ALL to overcome the vga=extended problem */ + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); +#if 0 + if(vesasuccess) { + vgaHWRestore(pScrn, vgaReg, (VGA_SR_CMAP | VGA_SR_FONTS)); + } else { + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + } +#endif + vgaHWProtect(pScrn, FALSE); } - - vgaHWProtect(pScrn, FALSE); - } + +#ifdef TWDEBUG + { + SISRegPtr pReg = &pSiS->ModeReg; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "REAL REGISTER CONTENTS AFTER RESTORE BY SETMODE:\n"); + (*pSiS->SiSSave)(pScrn, pReg); + } +#endif + + sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[0x05],sisReg->sisRegs3D4[0x80]); } else { /* All other chipsets */ vgaHWProtect(pScrn, TRUE); + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL); #endif + (*pSiS->SiSRestore)(pScrn, sisReg); vgaHWProtect(pScrn, TRUE); @@ -4387,8 +5937,8 @@ SISRestore(ScrnInfoPtr pScrn) vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); } - /* TW: Restore TV. This is rather complicated, but if we don't do it, - * TV output will flicker terribly + /* Restore TV. This is rather complicated, but if we don't do it, + * TV output will flicker terribly */ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { if(sisReg->sis6326tv[0] & 0x04) { @@ -4433,7 +5983,7 @@ SISVESARestore(ScrnInfoPtr pScrn) if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_RESTORE); } -/* TW: Restore bridge registers - to be called BEFORE VESARestore */ +/* Restore bridge config registers - to be called BEFORE VESARestore */ static void SISBridgeRestore(ScrnInfoPtr pScrn) { @@ -4449,7 +5999,7 @@ SISBridgeRestore(ScrnInfoPtr pScrn) } } -/* TW: Our generic BlockHandler for Xv */ +/* Our generic BlockHandler for Xv */ static void SISBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) { @@ -4469,9 +6019,9 @@ SISBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) /* Mandatory * This gets called at the start of each server generation * - * TW: We use pScrn and not CurrentLayout here, because the - * properties we use have not changed (displayWidth, - * depth, bitsPerPixel) + * We use pScrn and not CurrentLayout here, because the + * properties we use have not changed (displayWidth, + * depth, bitsPerPixel) */ static Bool SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) @@ -4495,14 +6045,24 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pSiS = SISPTR(pScrn); - if(pSiS->UseVESA) { +#ifdef SISDUALHEAD + if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) { +#endif + if(xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) - pSiS->pVbe = VBEInit(NULL, pSiS->pEnt->index); + pSiS->pVbe = VBEInit(NULL, pSiS->pEnt->index); #else - pSiS->pVbe = VBEExtendedInit(NULL, pSiS->pEnt->index, + pSiS->pVbe = VBEExtendedInit(NULL, pSiS->pEnt->index, SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); #endif + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to load VBE submodule\n"); + } +#ifdef SISDUALHEAD } +#endif #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { @@ -4521,9 +6081,9 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } vgaHWGetIOBase(hwp); - - /* TW: Patch the PIOOffset inside vgaHW to use - * our relocated IO ports. + + /* Patch the PIOOffset inside vgaHW to use + * our relocated IO ports. */ VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; @@ -4538,11 +6098,11 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - /* TW: Enable TurboQueue so that SISSave() saves it in enabled - * state. If we don't do this, X will hang after a restart! - * (Happens for some unknown reason only when using VESA - * for mode switching; assumingly a BIOS issue.) - * This is done on 300 and 310/325 series only. + /* Enable TurboQueue so that SISSave() saves it in enabled + * state. If we don't do this, X will hang after a restart! + * (Happens for some unknown reason only when using VESA + * for mode switching; assumingly a BIOS issue.) + * This is done on 300 and 315 series only. */ if(pSiS->UseVESA) { SiSEnableTurboQueue(pScrn); @@ -4550,10 +6110,61 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Save the current state */ SISSave(pScrn); - - /* TW: Save the current mode number */ + + OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay + * (pScrn->bitsPerPixel / 8); + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { - inSISIDXREG(SISCR, 0x34, pSiS->OldMode); + + if(!pSiS->OldMode) { + + /* Try to find out current (=old) mode number + * (Do this only if not sisfb has told us its mode yet) + */ + + /* Read 0:449 which the BIOS sets to the current mode number + * Unfortunately, this not reliable since the int10 emulation + * does not change this. So if we call the VBE later, this + * byte won't be touched. (which is why we set this manually + * then) + */ + unsigned char myoldmode = SiS_GetSetModeID(pScrn,0xFF); + unsigned char cr30, cr31; + + /* Read CR34 which the BIOS sets to the current mode number for CRT2 + * This is - of course - not reliable if the machine has no video + * bridge... + */ + inSISIDXREG(SISCR, 0x34, pSiS->OldMode); + inSISIDXREG(SISCR, 0x30, cr30); + inSISIDXREG(SISCR, 0x31, cr31); + + /* What if CR34 is different from the BIOS byte? */ + if(pSiS->OldMode != myoldmode) { + /* If no bridge output is active, trust the BIOS byte */ + if(!cr31 && !cr30) pSiS->OldMode = myoldmode; + /* ..else trust CR34 */ + } + + /* Newer 650 BIOSes set CR34 to 0xff if the mode has been + * "patched", for instance for 80x50 text mode. (That mode + * has no number of its own, it's 0x03 like 80x25). In this + * case, we trust the BIOS byte (provided that any of these + * two is valid). + */ + if(pSiS->OldMode > 0x7f) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Previous video mode (%02x) invalid, using BIOS scratch (%02x)\n", + pSiS->OldMode, myoldmode); + pSiS->OldMode = myoldmode; + } + } + + /* Clear frame buffer on 300 and 315/330 series + * (older chipsets don't like this to be done before + * setting the mode (such as rev 0x0b of 6326)) + */ + bzero(pSiS->FbBase, OnScreenSize); } /* Initialise the first mode */ @@ -4563,21 +6174,19 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } + /* Clear frame buffer */ + bzero(pSiS->FbBase, OnScreenSize); + /* Darken the screen for aesthetic reasons */ - /* TW: Not using Dual Head variant on purpose; we darken - * the screen for both displays, and un-darken - * it when the second head is finished + /* Not using Dual Head variant on purpose; we darken + * the screen for both displays, and un-darken + * it when the second head is finished */ SISSaveScreen(pScreen, SCREEN_SAVER_ON); /* Set the viewport */ SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - /* Clear frame buffer */ - OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay - * (pScrn->bitsPerPixel / 8); - bzero(pSiS->FbBase, OnScreenSize); - /* * The next step is to setup the screen's visuals, and initialise the * framebuffer code. In cases where the framebuffer's default @@ -4653,11 +6262,11 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif pSiS->cmdQueueLenPtr = &(pSiS->cmdQueueLen); - pSiS->cmdQueueLen = 0; /* TW: Force an EngineIdle() at start */ + pSiS->cmdQueueLen = 0; /* Force an EngineIdle() at start */ #ifdef XF86DRI #ifdef SISDUALHEAD - /* TW: No DRI in dual head mode */ + /* No DRI in dual head mode */ if(pSiS->DualHeadMode) { pSiS->directRenderingEnabled = FALSE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -4707,7 +6316,7 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ret = FALSE; break; } - if (!ret) { + if(!ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf1bpp/xf4bpp/fbScreenInit() failed\n"); SISSaveScreen(pScreen, SCREEN_SAVER_OFF); @@ -4746,7 +6355,7 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) SiS300AccelInit(pScreen); break; case SIS_315_VGA: - SiS310AccelInit(pScreen); + SiS315AccelInit(pScreen); break; default: SiSAccelInit(pScreen); @@ -4779,6 +6388,14 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } +#if 0 + if((pSiS->GammaBriR != 1000) || (pSiS->GammaBriG != 1000) || + (pSiS->GammaBriB != 1000) || (pSiS->GammaPBriR != 1000) || + (pSiS->GammaPBriG != 1000) || (pSiS->GammaPBriB != 1000)) { + SISCalculateGammaRamp(pScrn); + } +#endif + if(pSiS->ShadowFB) { RefreshAreaFuncPtr refreshArea = SISRefreshArea; @@ -4799,69 +6416,51 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ShadowFBInit(pScreen, refreshArea); } -#ifdef SISDUALHEAD - if(pSiS->DualHeadMode) - /* TW: DPMS for dual head mode */ - xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSetDH, 0); - else -#endif - xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0); + xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0); /* Init memPhysBase and fbOffset in pScrn */ pScrn->memPhysBase = pSiS->FbAddress; pScrn->fbOffset = 0; -#ifdef XvExtension +#if (XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,0,0)) || (defined(XvExtension)) if(!pSiS->NoXvideo) { -#ifdef SISDUALHEAD - /* TW: On chipsets with only one overlay, we support - * Xv only in "real" dual head mode, not Xinerama - */ - if ( ((pSiS->VGAEngine == SIS_300_VGA) || - (pSiS->VGAEngine == SIS_315_VGA) ) - && - ((pSiS->hasTwoOverlays) || - (!pSiS->DualHeadMode) || - (noPanoramiXExtension) ) ) { -#else - if ( (pSiS->VGAEngine == SIS_300_VGA) || - (pSiS->VGAEngine == SIS_315_VGA) ) { -#endif -#ifdef SISDUALHEAD - if (pSiS->DualHeadMode) { - if ( pSiS->hasTwoOverlays || - (pSiS->XvOnCRT2 && (!pSiS->SecondHead)) || - ((!pSiS->XvOnCRT2 && pSiS->SecondHead)) ) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using SiS300/310/325 series HW Xv on CRT%d\n", - (pSiS->SecondHead ? 1 : 2)); - SISInitVideo(pScreen); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using SiS300/310/325 series HW Xv on CRT%d\n", - (pSiS->SecondHead ? 1 : 2)); + if ( (pSiS->VGAEngine == SIS_300_VGA) || + (pSiS->VGAEngine == SIS_315_VGA) ) { +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using SiS300/315 series HW Xv on CRT%d\n", + (pSiS->SecondHead ? 1 : 2)); + if(!pSiS->hasTwoOverlays) { + if( (pSiS->XvOnCRT2 && pSiS->SecondHead) || + (!pSiS->XvOnCRT2 && !pSiS->SecondHead) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "However, overlay will by default only be visible on CRT%d\n", + pSiS->XvOnCRT2 ? 2 : 1); + } } + SISInitVideo(pScreen); } else { #endif - if (pSiS->hasTwoOverlays) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using SiS300/310/325 series HW Xv\n" ); + if(pSiS->hasTwoOverlays) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using SiS300/315 series HW Xv\n" ); else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using SiS300/310/325 series HW Xv on CRT%d\n", - (pSiS->XvOnCRT2 ? 2 : 1)); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using SiS300/315 series HW Xv by default on CRT%d\n", + (pSiS->XvOnCRT2 ? 2 : 1)); SISInitVideo(pScreen); #ifdef SISDUALHEAD } #endif -#ifdef USE6326VIDEO } else if( pSiS->Chipset == PCI_CHIP_SIS6326 || pSiS->Chipset == PCI_CHIP_SIS530 || pSiS->Chipset == PCI_CHIP_SIS5597 ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SiS5597/5598/6326/530/620 HW Xv\n" ); SIS6326InitVideo(pScreen); -#endif + } else { /* generic Xv */ XF86VideoAdaptorPtr *ptr; @@ -4872,9 +6471,7 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86XVScreenInit(pScreen, ptr, n); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using generic Xv\n" ); } - if (!noPanoramiXExtension) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "HW Xv not supported in Xinerama mode\n"); + } } #endif @@ -4895,14 +6492,36 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif + + /* Wrap some funcs */ + + pSiS->SiS_SD_Flags &= ~(SiS_SD_PSEUDOXINERAMA); +#ifdef SISMERGED + if(pSiS->MergedFB) { + pSiS->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = SISMergePointerMoved; + pSiS->Rotate = FALSE; + pSiS->ShadowFB = FALSE; +#ifdef SISXINERAMA + if(pSiS->UseSiSXinerama) { + SiSnoPanoramiXExtension = FALSE; + SiSXineramaExtensionInit(pScrn); + if(!SiSnoPanoramiXExtension) { + pSiS->SiS_SD_Flags |= SiS_SD_PSEUDOXINERAMA; + } + } +#endif + } +#endif + pSiS->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = SISCloseScreen; #ifdef SISDUALHEAD if(pSiS->DualHeadMode) - pScreen->SaveScreen = SISSaveScreenDH; + pScreen->SaveScreen = SISSaveScreenDH; else #endif - pScreen->SaveScreen = SISSaveScreen; + pScreen->SaveScreen = SISSaveScreen; /* Install BlockHandler */ pSiS->BlockHandler = pScreen->BlockHandler; @@ -4910,18 +6529,18 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Report any unused options (only for the first generation) */ if(serverGeneration == 1) { - xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); } /* Turn on the screen now */ /* TW: We do this in dual head mode after second head is finished */ #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { - if(pSiS->SecondHead) - SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + if(pSiS->SecondHead) + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); } else #endif - SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); return TRUE; } @@ -4939,7 +6558,19 @@ SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) } } - return SISModeInit(xf86Screens[scrnIndex], mode); + if(!(SISModeInit(xf86Screens[scrnIndex], mode))) return FALSE; + + /* Since RandR (indirectly) uses SwitchMode(), we need to + * update our Xinerama info here, too, in case of resizing + */ +#ifdef SISMERGED +#ifdef SISXINERAMA + if(pSiS->MergedFB) { + SiSUpdateXineramaScreenInfo(pScrn); + } +#endif +#endif + return TRUE; } #ifdef CYCLECRT2 @@ -4950,36 +6581,42 @@ SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SISPtr pSiS = SISPTR(pScrn); int i = 0; + BOOLEAN hcm; - /* TW: Only on 300 and 310/325 series */ + /* Only on 300 and 315/330 series */ if(pSiS->VGAEngine != SIS_300_VGA && pSiS->VGAEngine != SIS_315_VGA) return FALSE; - /* TW: Only if there is a video bridge */ - if(pSiS->VBFlags & VB_VIDEOBRIDGE) return FALSE; + /* Only if there is a video bridge */ + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return FALSE; - /* TW: Only if there were more than 1 CRT2 devices detected */ + /* Only if there were more than 1 CRT2 devices detected */ if(pSiS->detectedCRT2Devices & CRT2_VGA) i++; if(pSiS->detectedCRT2Devices & CRT2_LCD) i++; if(pSiS->detectedCRT2Devices & CRT2_TV) i++; if(i <= 1) return FALSE; - /* TW: Cycle CRT2 type */ + /* Cycle CRT2 type */ i = (pSiS->VBFlags & DISPTYPE_DISP2) << 1; while(!(i & pSiS->detectedCRT2Devices)) { i <<= 1; if(i > CRT2_VGA) i = CRT2_LCD; } +#ifdef SISMERGED + if(pSiS->MergedFB) hcm = pSiS->HaveCustomModes2; + else +#endif + hcm = pSiS->HaveCustomModes; - /* TW: Check if mode is suitable for desired output device */ + /* Check if the current mode is suitable for desired output device */ if(!SiS_CheckCalcModeIndex(pScrn, pScrn->currentMode, - ((pSiS->VBFlags & ~(DISPTYPE_DISP2)) | i))) { + ((pSiS->VBFlags & ~(DISPTYPE_DISP2)) | i), hcm)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Current mode not suitable for desired CRT2 output device\n"); return FALSE; } - /* TW: Sync the accelerators */ + /* Sync the accelerators */ if(!pSiS->NoAccel) { if(pSiS->AccelInfoPtr) { (*pSiS->AccelInfoPtr->Sync)(pScrn); @@ -4989,133 +6626,562 @@ SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode) pSiS->VBFlags &= ~(DISPTYPE_DISP2); pSiS->VBFlags |= i; - return SISModeInit(xf86Screens[scrnIndex], mode); + xf86DrvMsg(0, X_INFO, "Calling SiSModeInit()\n"); + + /* return SISModeInit(xf86Screens[scrnIndex], mode); */ + /* Remember to restore the palette after this */ + if(!(pScrn->SwitchMode(scrnIndex, pScrn->currentMode, 0))) return FALSE; + SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} +#endif + +Bool +SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) +{ + SISPtr pSiS = SISPTR(pScrn); + BOOLEAN hcm; + DisplayModePtr mode = pScrn->currentMode; + + /* Only on 300 and 315/330 series */ + if(pSiS->VGAEngine != SIS_300_VGA && + pSiS->VGAEngine != SIS_315_VGA) return FALSE; + + /* Only if there is a video bridge */ + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return FALSE; + +#define SiS_NewVBMask (CRT2_ENABLE | TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_AVIDEO | TV_SVIDEO) + + newvbflags &= SiS_NewVBMask; + newvbflags |= pSiS->VBFlags & ~SiS_NewVBMask; + +#ifdef SISMERGED + if(pSiS->MergedFB) { + hcm = pSiS->HaveCustomModes2; + if(mode->Private) { + mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; + } + if(!(newvbflags & CRT2_ENABLE)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT2 can't be switched off in MergedFB mode\n"); + return FALSE; + } + } else +#endif + hcm = pSiS->HaveCustomModes; + + if((!(newvbflags & CRT2_ENABLE)) && (!newvbflags & DISPTYPE_CRT1)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT2 can't be switched off if CRT1 is off, too\n"); + return FALSE; + } + + /* Check if the current mode is suitable for desired output device */ + if(!SiS_CheckCalcModeIndex(pScrn, mode, newvbflags, hcm)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Current mode not suitable for desired CRT2 output device\n"); + return FALSE; + } + + /* Sync the accelerators */ + if(!pSiS->NoAccel) { + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + } + + pSiS->VBFlags = pSiS->VBFlags_backup = newvbflags; + + if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE; + /* if(!SISModeInit(xf86Screens[pScrn->scrnIndex], pScrn->currentMode)) return FALSE; */ + SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + +Bool +SISCheckModeIndexForCRT2Type(ScrnInfoPtr pScrn, unsigned short cond, unsigned short index) +{ + SISPtr pSiS = SISPTR(pScrn); + BOOLEAN hcm; + DisplayModePtr mode = pScrn->modes; + int i; + unsigned long vbflags = pSiS->VBFlags; + + /* Only on 300 and 315/330 series */ + if(pSiS->VGAEngine != SIS_300_VGA && + pSiS->VGAEngine != SIS_315_VGA) return FALSE; + + /* Mode is OK if there is no video bridge */ + /* (Requires screen size check in app) */ + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return TRUE; + + if(cond) { + vbflags &= ~(CRT2_ENABLE | TV_TYPE | TV_PALM | TV_PALN); + if(cond & SiS_CF2_LCD) { + vbflags |= CRT2_LCD; + } else if(cond & SiS_CF2_TV) { + vbflags |= CRT2_TV; + if(cond & SiS_CF2_TVPAL) vbflags |= TV_PAL; + else if(cond & SiS_CF2_TVPALM) vbflags |= (TV_PAL | TV_PALM); + else if(cond & SiS_CF2_TVPALN) vbflags |= (TV_PAL | TV_PALN); + else if(cond & SiS_CF2_TVNTSC) vbflags |= TV_NTSC; + } else if(cond & SiS_CF2_VGA2) { + vbflags |= CRT2_VGA; + } + } + + /* Mode is obviously OK if video bridge is disabled */ + /* (Required extra check for eventual screen size problems in app) */ + if(!(vbflags & CRT2_ENABLE)) return TRUE; + + /* Find mode of given index */ + if(index) { + for(i = 0; i < index; i++) { + if(!mode) return FALSE; + mode = mode->next; + } + } + +#ifdef SISMERGED + if(pSiS->MergedFB) { + hcm = pSiS->HaveCustomModes2; + if(mode->Private) { + mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; + } + } else +#endif + hcm = pSiS->HaveCustomModes; + + /* For RandR */ + if((mode->HDisplay > pScrn->virtualX) || (mode->VDisplay > pScrn->virtualY)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Desired mode too large for current screen size\n"); + return FALSE; + } + + /* Check if the desired mode is suitable for current output device */ + if(!SiS_CheckCalcModeIndex(pScrn, mode, vbflags, hcm)) { + if(!cond) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Desired mode not suitable for current CRT2 output device\n"); + } + return FALSE; + } + + return TRUE; +} + +Bool +SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) +{ + SISPtr pSiS = SISPTR(pScrn); + + /* Only on 300 and 315/330 series */ + if(pSiS->VGAEngine != SIS_300_VGA && + pSiS->VGAEngine != SIS_315_VGA) return FALSE; + + /* Only if at least one CRT2 device is active */ + if(!(pSiS->VBFlags & CRT2_ENABLE)) return FALSE; + +#ifdef SISMERGED + if(pSiS->MergedFB) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT1 can't be switched off in MergedFB mode\n"); + return FALSE; + } +#endif + + pSiS->VBFlags &= ~(DISPTYPE_CRT1 | SINGLE_MODE | MIRROR_MODE); + pSiS->CRT1off = 1; + if(onoff) { + pSiS->VBFlags |= DISPTYPE_CRT1; + pSiS->CRT1off = 0; + if(pSiS->VBFlags & CRT2_ENABLE) pSiS->VBFlags |= MIRROR_MODE; + else pSiS->VBFlags |= SINGLE_MODE; + } else { + pSiS->VBFlags |= SINGLE_MODE; + } + + pSiS->VBFlags_backup = pSiS->VBFlags; + + /* Sync the accelerators */ + if(!pSiS->NoAccel) { + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + } + + if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE; + /* if(!SISModeInit(xf86Screens[pScrn->scrnIndex], pScrn->currentMode)) return FALSE; */ + SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + +static void +SISSetStartAddressCRT1(SISPtr pSiS, unsigned long base) +{ + unsigned char cr11backup; + + inSISIDXREG(SISCR, 0x11, cr11backup); /* Unlock CRTC registers */ + andSISIDXREG(SISCR, 0x11, 0x7F); + outSISIDXREG(SISCR, 0x0D, base & 0xFF); + outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); + outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); + if(pSiS->VGAEngine == SIS_315_VGA) { + setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); + } + /* Eventually lock CRTC registers */ + setSISIDXREG(SISCR, 0x11, 0x7F,(cr11backup & 0x80)); +} + +static void +SISSetStartAddressCRT2(SISPtr pSiS, unsigned long base) +{ + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + outSISIDXREG(SISPART1, 0x06, GETVAR8(base)); + outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8)); + outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16)); + if(pSiS->VGAEngine == SIS_315_VGA) { + setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); + } + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); +} + +#ifdef SISMERGED +Bool +InRegion(int x, int y, region r) +{ + return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1); +} + +static void +SISAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned long base; + + base = y * pSiS->CurrentLayout.displayWidth + x; + switch(pSiS->CurrentLayout.bitsPerPixel) { + case 16: base >>= 1; break; + case 32: break; + default: base >>= 2; + } + SISSetStartAddressCRT1(pSiS, base); +} + +static void +SISAdjustFrameHW_CRT2(ScrnInfoPtr pScrn, int x, int y) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned long base; + + base = y * pSiS->CurrentLayout.displayWidth + x; + switch(pSiS->CurrentLayout.bitsPerPixel) { + case 16: base >>= 1; break; + case 32: break; + default: base >>= 2; + } + SISSetStartAddressCRT2(pSiS, base); +} + +void +SISMergePointerMoved(int scrnIndex, int x, int y) +{ + ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; + SISPtr pSiS = SISPTR(pScrn1); + ScrnInfoPtr pScrn2 = pSiS->CRT2pScrn; + region out, in1, in2, f2, f1; + int deltax, deltay; + + f1.x0 = pSiS->CRT1frameX0; + f1.x1 = pSiS->CRT1frameX1; + f1.y0 = pSiS->CRT1frameY0; + f1.y1 = pSiS->CRT1frameY1; + f2.x0 = pScrn2->frameX0; + f2.x1 = pScrn2->frameX1; + f2.y0 = pScrn2->frameY0; + f2.y1 = pScrn2->frameY1; + + /* Define the outer region. Crossing this causes all frames to move */ + out.x0 = pScrn1->frameX0; + out.x1 = pScrn1->frameX1; + out.y0 = pScrn1->frameY0; + out.y1 = pScrn1->frameY1; + + /* + * Define the inner sliding window. Being outsize both frames but + * inside the outer clipping window will slide corresponding frame + */ + in1 = out; + in2 = out; + switch(((SiSMergedDisplayModePtr)pSiS->CurrentLayout.mode->Private)->CRT2Position) { + case sisLeftOf: + in1.x0 = f1.x0; + in2.x1 = f2.x1; + break; + case sisRightOf: + in1.x1 = f1.x1; + in2.x0 = f2.x0; + break; + case sisBelow: + in1.y1 = f1.y1; + in2.y0 = f2.y0; + break; + case sisAbove: + in1.y0 = f1.y0; + in2.y1 = f2.y1; + break; + case sisClone: + break; + } + + deltay = 0; + deltax = 0; + + if(InRegion(x, y, out)) { /* inside outer region */ + + if(InRegion(x, y, in1) && !InRegion(x, y, f1)) { + REBOUND(f1.x0, f1.x1, x); + REBOUND(f1.y0, f1.y1, y); + deltax = 1; + } + if(InRegion(x, y, in2) && !InRegion(x, y, f2)) { + REBOUND(f2.x0, f2.x1, x); + REBOUND(f2.y0, f2.y1, y); + deltax = 1; + } + + } else { /* outside outer region */ + + if(out.x0 > x) { + deltax = x - out.x0; + } + if(out.x1 < x) { + deltax = x - out.x1; + } + if(deltax) { + pScrn1->frameX0 += deltax; + pScrn1->frameX1 += deltax; + f1.x0 += deltax; + f1.x1 += deltax; + f2.x0 += deltax; + f2.x1 += deltax; + } + + if(out.y0 > y) { + deltay = y - out.y0; + } + if(out.y1 < y) { + deltay = y - out.y1; + } + if(deltay) { + pScrn1->frameY0 += deltay; + pScrn1->frameY1 += deltay; + f1.y0 += deltay; + f1.y1 += deltay; + f2.y0 += deltay; + f2.y1 += deltay; + } + + switch(((SiSMergedDisplayModePtr)pSiS->CurrentLayout.mode->Private)->CRT2Position) { + case sisLeftOf: + if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); } + if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); } + break; + case sisRightOf: + if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); } + if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); } + break; + case sisBelow: + if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); } + if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); } + break; + case sisAbove: + if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); } + if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); } + break; + case sisClone: + break; + } + + } + + if(deltax || deltay) { + pSiS->CRT1frameX0 = f1.x0; + pSiS->CRT1frameY0 = f1.y0; + pScrn2->frameX0 = f2.x0; + pScrn2->frameY0 = f2.y0; + + pSiS->CRT1frameX1 = pSiS->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1; + pSiS->CRT1frameY1 = pSiS->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1; + pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1; + pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1; + pScrn1->frameX1 = pScrn1->frameX0 + pSiS->CurrentLayout.mode->HDisplay - 1; + pScrn1->frameY1 = pScrn1->frameY0 + pSiS->CurrentLayout.mode->VDisplay - 1; + + SISAdjustFrameHW_CRT1(pScrn1, pSiS->CRT1frameX0, pSiS->CRT1frameY0); + SISAdjustFrameHW_CRT2(pScrn1, pScrn2->frameX0, pScrn2->frameY0); + } +} + +static void +SISAdjustFrameMerged(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; + SISPtr pSiS = SISPTR(pScrn1); + ScrnInfoPtr pScrn2 = pSiS->CRT2pScrn; + int VTotal = pSiS->CurrentLayout.mode->VDisplay; + int HTotal = pSiS->CurrentLayout.mode->HDisplay; + int VMax = VTotal; + int HMax = HTotal; + + BOUND(x, 0, pScrn1->virtualX - HTotal); + BOUND(y, 0, pScrn1->virtualY - VTotal); + + switch(SDMPTR(pScrn1)->CRT2Position) { + case sisLeftOf: + pScrn2->frameX0 = x; + BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); + pSiS->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay; + BOUND(pSiS->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); + break; + case sisRightOf: + pSiS->CRT1frameX0 = x; + BOUND(pSiS->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); + pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay; + BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); + break; + case sisAbove: + BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); + pScrn2->frameY0 = y; + BOUND(pSiS->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); + pSiS->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay; + break; + case sisBelow: + BOUND(pSiS->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); + pSiS->CRT1frameY0 = y; + BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); + pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay; + break; + case sisClone: + BOUND(pSiS->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); + BOUND(pSiS->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); + BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); + BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); + break; + } + + BOUND(pSiS->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay); + BOUND(pSiS->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay); + BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay); + BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay); + + pScrn1->frameX0 = x; + pScrn1->frameY0 = y; + + pSiS->CRT1frameX1 = pSiS->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1; + pSiS->CRT1frameY1 = pSiS->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1; + pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1; + pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1; + pScrn1->frameX1 = pScrn1->frameX0 + pSiS->CurrentLayout.mode->HDisplay - 1; + pScrn1->frameY1 = pScrn1->frameY0 + pSiS->CurrentLayout.mode->VDisplay - 1; + + SISAdjustFrameHW_CRT1(pScrn1, pSiS->CRT1frameX0, pSiS->CRT1frameY0); + SISAdjustFrameHW_CRT2(pScrn1, pScrn2->frameX0, pScrn2->frameY0); } #endif /* * This function is used to initialize the Start Address - the first * displayed location in the video memory. + * + * Usually mandatory */ -/* Usually mandatory */ void SISAdjustFrame(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - SISPtr pSiS; - vgaHWPtr hwp; - int base; - unsigned char temp; - - hwp = VGAHWPTR(pScrn); - pSiS = SISPTR(pScrn); - - base = y * pSiS->CurrentLayout.displayWidth + x; + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SISPtr pSiS = SISPTR(pScrn); + unsigned long base; + unsigned char temp, cr11backup; + +#ifdef SISMERGED + if(pSiS->MergedFB) { + SISAdjustFrameMerged(scrnIndex, x, y, flags); + return; + } +#endif if(pSiS->UseVESA) { - - /* TW: Let BIOS adjust frame if using VESA */ VBESetDisplayStart(pSiS->pVbe, x, y, TRUE); + return; + } + if(pScrn->bitsPerPixel < 8) { + base = (y * pSiS->CurrentLayout.displayWidth + x + 3) >> 3; } else { + base = y * pSiS->CurrentLayout.displayWidth + x; + + /* calculate base bpp dep. */ + switch(pSiS->CurrentLayout.bitsPerPixel) { + case 16: + base >>= 1; + break; + case 24: + base = ((base * 3)) >> 2; + base -= base % 6; + break; + case 32: + break; + default: /* 8bpp */ + base >>= 2; + break; + } + } #ifdef UNLOCK_ALWAYS - sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - if(pScrn->bitsPerPixel < 8) { - base = (y * pSiS->CurrentLayout.displayWidth + x + 3) >> 3; - } else { - base = y * pSiS->CurrentLayout.displayWidth + x; - - /* calculate base bpp dep. */ - switch(pSiS->CurrentLayout.bitsPerPixel) { - case 16: - base >>= 1; - break; - case 24: - base = ((base * 3)) >> 2; - base -= base % 6; - break; - case 32: - break; - default: /* 8bpp */ - base >>= 2; - break; - } - } - -#ifdef SISDUALHEAD - if (pSiS->DualHeadMode) { - /* TW: We assume that DualHeadMode only can be true for - * dual head capable chipsets (and thus save the check - * for chipset here) - */ - if (!pSiS->SecondHead) { - /* TW: Head 1 (master) is always CRT2 */ - SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - outSISIDXREG(SISPART1, 0x06, GETVAR8(base)); - outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8)); - outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16)); - if (pSiS->VGAEngine == SIS_315_VGA) { - setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); - } - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - } else { - /* TW: Head 2 (slave) is always CRT1 */ - base += (pSiS->dhmOffset/4); - outSISIDXREG(SISCR, 0x0D, base & 0xFF); - outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); - outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); - if (pSiS->VGAEngine == SIS_315_VGA) { - setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); - } - } - } else { +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->SecondHead) { + /* Head 1 (master) is always CRT2 */ + SISSetStartAddressCRT2(pSiS, base); + } else { + /* TW: Head 2 (slave) is always CRT1 */ + base += (pSiS->dhmOffset/4); + SISSetStartAddressCRT1(pSiS, base); + } + } else { #endif - switch (pSiS->VGAEngine) { - case SIS_300_VGA: - outSISIDXREG(SISCR, 0x0D, base & 0xFF); - outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); - outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); - if (pSiS->VBFlags & CRT2_ENABLE) { - SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - outSISIDXREG(SISPART1, 0x06, GETVAR8(base)); - outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8)); - outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16)); - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - } - break; - case SIS_315_VGA: - outSISIDXREG(SISCR, 0x0D, base & 0xFF); - outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); - outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); - setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); - if (pSiS->VBFlags & CRT2_ENABLE) { - SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - outSISIDXREG(SISPART1, 0x06, GETVAR8(base)); - outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8)); - outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16)); - setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - } - break; - default: - outSISIDXREG(SISCR, 0x0D, base & 0xFF); - outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); - inSISIDXREG(SISSR, 0x27, temp); - temp &= 0xF0; - temp |= (base & 0x0F0000) >> 16; - outSISIDXREG(SISSR, 0x27, temp); - } + switch(pSiS->VGAEngine) { + case SIS_300_VGA: + case SIS_315_VGA: + SISSetStartAddressCRT1(pSiS, base); + if(pSiS->VBFlags & CRT2_ENABLE) { + SISSetStartAddressCRT2(pSiS, base); + } + break; + default: + /* Unlock CRTC registers */ + inSISIDXREG(SISCR, 0x11, cr11backup); + andSISIDXREG(SISCR, 0x11, 0x7F); + outSISIDXREG(SISCR, 0x0D, base & 0xFF); + outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); + inSISIDXREG(SISSR, 0x27, temp); + temp &= 0xF0; + temp |= (base & 0x0F0000) >> 16; + outSISIDXREG(SISSR, 0x27, temp); + /* Eventually lock CRTC registers */ + setSISIDXREG(SISCR, 0x11, 0x7F, (cr11backup & 0x80)); + } #ifdef SISDUALHEAD - } + } #endif - } /* if not VESA */ } - /* * This is called when VT switching back to the X server. Its job is * to reinitialise the video mode. @@ -5138,7 +7204,7 @@ SISEnterVT(int scrnIndex, int flags) SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); #ifdef XF86DRI - /* TW: this is to be done AFTER switching the mode */ + /* this is to be done AFTER switching the mode */ if(pSiS->directRenderingEnabled) DRIUnlock(screenInfo.screens[scrnIndex]); #endif @@ -5160,7 +7226,7 @@ SISLeaveVT(int scrnIndex, int flags) #ifdef XF86DRI ScreenPtr pScreen; - /* TW: to be done before mode change */ + /* to be done before mode change */ if(pSiS->directRenderingEnabled) { pScreen = screenInfo.screens[scrnIndex]; DRILock(pScreen, 0); @@ -5193,20 +7259,29 @@ SISLeaveVT(int scrnIndex, int flags) if(pSiS->UseVESA) { - /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2, - * VBESaveRestore() does not restore CRT1. So we set any mode now, - * because VBESetVBEMode correctly restores CRT1. Afterwards, we - * can call VBESaveRestore to restore original mode. - */ - if ( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)) ) - VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL); + /* This is a q&d work-around for a BIOS bug. In case we disabled CRT2, + * VBESaveRestore() does not restore CRT1. So we set any mode now, + * because VBESetVBEMode correctly restores CRT1. Afterwards, we + * can call VBESaveRestore to restore original mode. + */ + if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2))) + VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL); - SISVESARestore(pScrn); + SISVESARestore(pScrn); } else { - + SISRestore(pScrn); - + + } + + /* We use this (otherwise unused) bit to indicate that we are running + * to keep sisfb to change the displaymode (this would result in + * lethal display corruption upon quitting X or changing to a VT + * until a reboot) + */ + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + orSISIDXREG(SISCR,0x34,0x80); } vgaHWLock(hwp); @@ -5230,15 +7305,15 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) #ifdef XF86DRI if(pSiS->directRenderingEnabled) { - SISDRICloseScreen(pScreen); - pSiS->directRenderingEnabled = FALSE; + SISDRICloseScreen(pScreen); + pSiS->directRenderingEnabled = FALSE; } #endif if(pScrn->vtSema) { if(pSiS->CursorInfoPtr) { -#ifdef SISDUALHEAD +#ifdef SISDUALHEAD if(pSiS->DualHeadMode) { if(!pSiS->SecondHead) { pSiS->ForceCursorOff = TRUE; @@ -5246,26 +7321,26 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) SISWaitVBRetrace(pScrn); pSiS->ForceCursorOff = FALSE; } - } else { + } else { #endif pSiS->CursorInfoPtr->HideCursor(pScrn); SISWaitVBRetrace(pScrn); -#ifdef SISDUALHEAD - } -#endif +#ifdef SISDUALHEAD + } +#endif } SISBridgeRestore(pScrn); if(pSiS->UseVESA) { - /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2, - * VBESaveRestore() does not restore CRT1. So we set any mode now, - * because VBESetVBEMode correctly restores CRT1. Afterwards, we - * can call VBESaveRestore to restore original mode. + /* This is a q&d work-around for a BIOS bug. In case we disabled CRT2, + * VBESaveRestore() does not restore CRT1. So we set any mode now, + * because VBESetVBEMode correctly restores CRT1. Afterwards, we + * can call VBESaveRestore to restore original mode. */ - if( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2))) - VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL); + if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2))) + VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL); SISVESARestore(pScrn); @@ -5278,44 +7353,89 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) vgaHWLock(hwp); } + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + andSISIDXREG(SISCR,0x34,0x7f); + } + SISUnmapMem(pScrn); vgaHWUnmapMem(pScrn); - + #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { pSiSEnt = pSiS->entityPrivate; pSiSEnt->refCount--; } -#endif +#endif + +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(pScrn->modes) { + pScrn->currentMode = pScrn->modes; + do { + DisplayModePtr p = pScrn->currentMode->next; + if(pScrn->currentMode->Private) + xfree(pScrn->currentMode->Private); + xfree(pScrn->currentMode); + pScrn->currentMode = p; + } while(pScrn->currentMode != pScrn->modes); + } + pScrn->currentMode = pSiS->CRT1CurrentMode; + pScrn->modes = pSiS->CRT1Modes; + pSiS->CRT1CurrentMode = NULL; + pSiS->CRT1Modes = NULL; + + if(pSiS->CRT2pScrn) { + if(pSiS->CRT2pScrn->modes) { + while(pSiS->CRT2pScrn->modes) + xf86DeleteMode(&pSiS->CRT2pScrn->modes, pSiS->CRT2pScrn->modes); + } + if(pSiS->CRT2pScrn->monitor) { + if(pSiS->CRT2pScrn->monitor->Modes) { + while(pSiS->CRT2pScrn->monitor->Modes) + xf86DeleteMode(&pSiS->CRT2pScrn->monitor->Modes, pSiS->CRT2pScrn->monitor->Modes); + } + if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC); + xfree(pSiS->CRT2pScrn->monitor); + } + xfree(pSiS->CRT2pScrn); + pSiS->CRT2pScrn = NULL; + } + } +#endif if(pSiS->pInt) { - xf86FreeInt10(pSiS->pInt); - pSiS->pInt = NULL; + xf86FreeInt10(pSiS->pInt); + pSiS->pInt = NULL; + } + + if(pSiS->AccelLinearScratch) { + xf86FreeOffscreenLinear(pSiS->AccelLinearScratch); + pSiS->AccelLinearScratch = NULL; } if(pSiS->AccelInfoPtr) { - XAADestroyInfoRec(pSiS->AccelInfoPtr); - pSiS->AccelInfoPtr = NULL; + XAADestroyInfoRec(pSiS->AccelInfoPtr); + pSiS->AccelInfoPtr = NULL; } if(pSiS->CursorInfoPtr) { - xf86DestroyCursorInfoRec(pSiS->CursorInfoPtr); - pSiS->CursorInfoPtr = NULL; + xf86DestroyCursorInfoRec(pSiS->CursorInfoPtr); + pSiS->CursorInfoPtr = NULL; } if(pSiS->ShadowPtr) { - xfree(pSiS->ShadowPtr); - pSiS->ShadowPtr = NULL; + xfree(pSiS->ShadowPtr); + pSiS->ShadowPtr = NULL; } if(pSiS->DGAModes) { - xfree(pSiS->DGAModes); - pSiS->DGAModes = NULL; + xfree(pSiS->DGAModes); + pSiS->DGAModes = NULL; } if(pSiS->adaptor) { - xfree(pSiS->adaptor); - pSiS->adaptor = NULL; + xfree(pSiS->adaptor); + pSiS->adaptor = NULL; } pScrn->vtSema = FALSE; @@ -5324,7 +7444,7 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) pScreen->BlockHandler = pSiS->BlockHandler; pScreen->CloseScreen = pSiS->CloseScreen; - return (*pScreen->CloseScreen)(scrnIndex, pScreen); + return(*pScreen->CloseScreen)(scrnIndex, pScreen); } @@ -5334,15 +7454,14 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) static void SISFreeScreen(int scrnIndex, int flags) { - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) - vgaHWFreeHWRec(xf86Screens[scrnIndex]); + if(xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); SISFreeRec(xf86Screens[scrnIndex]); } /* Checks if a mode is suitable for the selected chipset. */ -/* Optional */ static int SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { @@ -5350,36 +7469,56 @@ SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) SISPtr pSiS = SISPTR(pScrn); if(pSiS->UseVESA) { - if(SiSCalcVESAModeIndex(pScrn, mode)) - return(MODE_OK); - else - return(MODE_BAD); + if(SiSCalcVESAModeIndex(pScrn, mode)) + return(MODE_OK); + else + return(MODE_BAD); } if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { #ifdef SISDUALHEAD - if((pSiS->DualHeadMode) && (pSiS->SecondHead)) { - /* DHM: Only check modes for CRT1 */ - if(SiS_CalcModeIndex(pScrn, mode) < 0x14) - return(MODE_BAD); - } else -#endif - if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags) < 0x14) + if((pSiS->DualHeadMode) && (pSiS->SecondHead)) { + if(SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes) < 0x14) + return(MODE_BAD); + } else +#endif +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(!mode->Private) { + if(!pSiS->CheckForCRT2) { + if(SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes) < 0x14) + return(MODE_BAD); + } else { + if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes2) < 0x14) + return(MODE_BAD); + } + } else { + if(SiS_CalcModeIndex(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT1, + pSiS->HaveCustomModes) < 0x14) return(MODE_BAD); + if(SiS_CheckCalcModeIndex(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT2, + pSiS->VBFlags, pSiS->HaveCustomModes2) < 0x14) + return(MODE_BAD); + } + } else +#endif + if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) + return(MODE_BAD); } - + return(MODE_OK); } -/* Do screen blanking */ - -/* Mandatory */ +/* Do screen blanking + * + * Mandatory + */ static Bool SISSaveScreen(ScreenPtr pScreen, int mode) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - if ((pScrn != NULL) && pScrn->vtSema) { + if((pScrn != NULL) && pScrn->vtSema) { SISPtr pSiS = SISPTR(pScrn); @@ -5390,29 +7529,26 @@ SISSaveScreen(ScreenPtr pScreen, int mode) if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { - if(!xf86IsUnblank(mode)) { - pSiS->Blank = TRUE; - SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); - } else { - pSiS->Blank = FALSE; - SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); - } - } else { - /* if not blanked obtain state of LCD blank flags set by BIOS */ + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { + if(!xf86IsUnblank(mode)) { + pSiS->Blank = TRUE; + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + pSiS->Blank = FALSE; + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } else if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) { if(!pSiS->Blank) { inSISIDXREG(SISSR, 0x11, pSiS->LCDon); } - if(!xf86IsUnblank(mode)) { pSiS->Blank = TRUE; outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08); } else { pSiS->Blank = FALSE; - /* don't just unblanking; use LCD state set by BIOS */ outSISIDXREG(SISSR, 0x11, pSiS->LCDon); } - } + } } else if(pSiS->VGAEngine == SIS_315_VGA) { @@ -5426,7 +7562,7 @@ SISSaveScreen(ScreenPtr pScreen, int mode) SiS_Chrontel701xBLOff(pSiS->SiS_Pr); } else { pSiS->Blank = FALSE; - SiS_Chrontel701xBLOn(pSiS->SiS_Pr); + SiS_Chrontel701xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); } } else if(pSiS->VBFlags & VB_LVDS) { if(!xf86IsUnblank(mode)) { @@ -5436,7 +7572,7 @@ SISSaveScreen(ScreenPtr pScreen, int mode) pSiS->Blank = FALSE; outSISIDXREG(SISSR, 0x11, pSiS->LCDon); } - } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) { + } else if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { if(!xf86IsUnblank(mode)) { pSiS->Blank = TRUE; SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -5454,13 +7590,13 @@ SISSaveScreen(ScreenPtr pScreen, int mode) } #ifdef SISDUALHEAD -/* TW: SaveScreen for dual head mode */ +/* SaveScreen for dual head mode */ static Bool SISSaveScreenDH(ScreenPtr pScreen, int mode) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - if ((pScrn != NULL) && pScrn->vtSema) { + if((pScrn != NULL) && pScrn->vtSema) { SISPtr pSiS = SISPTR(pScrn); if (pSiS->SecondHead) { @@ -5482,7 +7618,7 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { if(!xf86IsUnblank(mode)) { pSiS->BlankCRT2 = TRUE; SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -5490,18 +7626,15 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) pSiS->BlankCRT2 = FALSE; SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); } - } else { - /* if not blanked obtain state of LCD blank flags set by BIOS */ + } else if(pSiS->VBFlags & (VB_LVDS|VB_30xBDH)) { if(!pSiS->BlankCRT2) { inSISIDXREG(SISSR, 0x11, pSiS->LCDon); } - if (!xf86IsUnblank(mode)) { pSiS->BlankCRT2 = TRUE; outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08); } else { pSiS->BlankCRT2 = FALSE; - /* don't just unblank; use LCD state set by BIOS */ outSISIDXREG(SISSR, 0x11, pSiS->LCDon); } } @@ -5518,7 +7651,7 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) SiS_Chrontel701xBLOff(pSiS->SiS_Pr); } else { pSiS->BlankCRT2 = FALSE; - SiS_Chrontel701xBLOn(pSiS->SiS_Pr); + SiS_Chrontel701xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); } } else if(pSiS->VBFlags & VB_LVDS) { if(!xf86IsUnblank(mode)) { @@ -5528,7 +7661,7 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) pSiS->BlankCRT2 = FALSE; outSISIDXREG(SISSR, 0x11, pSiS->LCDon); } - } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) { + } else if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { if(!xf86IsUnblank(mode)) { pSiS->BlankCRT2 = TRUE; SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -5546,7 +7679,6 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) #endif #ifdef DEBUG -/* locally used for debug */ static void SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode) { @@ -5569,11 +7701,9 @@ SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode) } #endif -/* local used for debug */ static void SISModifyModeInfo(DisplayModePtr mode) { -#if 1 if(mode->CrtcHBlankStart == mode->CrtcHDisplay) mode->CrtcHBlankStart++; if(mode->CrtcHBlankEnd == mode->CrtcHTotal) @@ -5582,10 +7712,9 @@ SISModifyModeInfo(DisplayModePtr mode) mode->CrtcVBlankStart++; if(mode->CrtcVBlankEnd == mode->CrtcVTotal) mode->CrtcVBlankEnd--; -#endif } -/* TW: Enable the TurboQueue (For 300 and 310/325 series only) */ +/* Enable the TurboQueue (For 300 and 315/330 series only) */ void SiSEnableTurboQueue(ScrnInfoPtr pScrn) { @@ -5608,8 +7737,8 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) break; case SIS_315_VGA: if (!pSiS->NoAccel) { - /* TW: On 310/325 series, there are three queue modes available - * which are chosen by setting bits 7:5 in SR26: + /* On 315 series, there are three queue modes available + * which are chosen by setting bits 7:5 in SR26: * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep * track of the queue, the FIFO, command parsing and so * on. This is the one comparable to the 300 series. @@ -5640,26 +7769,26 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) #if 0 if (pSiS->TurboQueue) { #endif - /* TW: We only use MMIO Cmd Queue, not VRAM or AGP */ - /* TW: Set Command Queue Threshold to max value 11111b */ + /* We only use MMIO Cmd Queue, not VRAM or AGP */ + /* Set Command Queue Threshold to max value 11111b */ outSISIDXREG(SISSR, 0x27, 0x1F); - /* TW: Syncronous reset for Command Queue */ + /* Syncronous reset for Command Queue */ outSISIDXREG(SISSR, 0x26, 0x01); - /* TW: Do some magic (cp readport to writeport) */ + /* Do some magic (cp readport to writeport) */ temp = MMIO_IN32(pSiS->IOBase, 0x85C8); MMIO_OUT32(pSiS->IOBase, 0x85C4, temp); - /* TW: Enable MMIO Command Queue mode (0x20), - * Enable_command_queue_auto_correction (0x02) - * (no idea, but sounds good, so use it) - * 512k (0x00) (does this apply to MMIO mode?) */ + /* Enable MMIO Command Queue mode (0x20), + * Enable_command_queue_auto_correction (0x02) + * (no idea, but sounds good, so use it) + * 512k (0x00) (does this apply to MMIO mode?) */ outSISIDXREG(SISSR, 0x26, 0x22); - /* TW: Calc Command Queue position (Q is always 512k)*/ + /* Calc Command Queue position (Q is always 512k)*/ temp = (pScrn->videoRam - 512) * 1024; - /* TW: Set Q position */ + /* Set Q position */ MMIO_OUT32(pSiS->IOBase, 0x85C0, temp); #if 0 } else { - /* TW: Is there a non-TurboQueue mode within MMIO mode? */ + /* Is there a non-TurboQueue mode within MMIO mode? */ } #endif } @@ -5669,8 +7798,8 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) } } -/* TW: Things to do before a ModeSwitch. We set up the - * video bridge configuration and the TurboQueue. +/* Things to do before a ModeSwitch. We set up the + * video bridge configuration and the TurboQueue. */ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) { @@ -5678,36 +7807,155 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) unsigned char usScratchCR30, usScratchCR31; unsigned char usScratchCR32, usScratchCR33; unsigned char usScratchCR17, usScratchCR38 = 0; - int vbflag, temp = 0; + unsigned char usScratchCR79 = 0; + unsigned long vbflag; + int temp = 0, i; int crt1rateindex = 0; + DisplayModePtr mymode; +#ifdef SISMERGED + DisplayModePtr mymode2 = NULL; +#endif -#ifdef UNLOCK_ALWAYS - sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); /* Unlock Registers */ +#ifdef SISMERGED + if(pSiS->MergedFB) { + mymode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1; + mymode2 = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; + } else #endif + mymode = mode; vbflag = pSiS->VBFlags; pSiS->IsCustom = FALSE; - - if(pSiS->HaveCustomModes) { - if(!(mode->type & M_T_DEFAULT)) { - pSiS->IsCustom = TRUE; +#ifdef SISMERGED + pSiS->IsCustomCRT2 = FALSE; + + if(pSiS->MergedFB) { + /* CRT2 */ + if(vbflag & CRT2_LCD) { + if(pSiS->SiS_Pr->CP_HaveCustomData) { + for(i=0; i<7; i++) { + if(pSiS->SiS_Pr->CP_DataValid[i]) { + if((mymode2->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) && + (mymode2->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) { + if(mymode2->type & M_T_BUILTIN) { + pSiS->IsCustomCRT2 = TRUE; + } + } + } + } + } + } + if(vbflag & (CRT2_VGA|CRT2_LCD)) { + if(pSiS->AddedPlasmaModes) { + if(mymode2->type & M_T_BUILTIN) { + pSiS->IsCustomCRT2 = TRUE; + } + } + if(pSiS->HaveCustomModes2) { + if(!(mymode2->type & M_T_DEFAULT)) { + pSiS->IsCustomCRT2 = TRUE; + } + } + } + /* CRT1 */ + if(pSiS->HaveCustomModes) { + if(!(mymode->type & M_T_DEFAULT)) { + pSiS->IsCustom = TRUE; + } + } + } else +#endif +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->SecondHead) { + /* CRT2 */ + if(vbflag & CRT2_LCD) { + if(pSiS->SiS_Pr->CP_HaveCustomData) { + for(i=0; i<7; i++) { + if(pSiS->SiS_Pr->CP_DataValid[i]) { + if((mymode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) && + (mymode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) { + if(mymode->type & M_T_BUILTIN) { + pSiS->IsCustom = TRUE; + } + } + } + } + } + } + if(vbflag & (CRT2_VGA|CRT2_LCD)) { + if(pSiS->AddedPlasmaModes) { + if(mymode->type & M_T_BUILTIN) { + pSiS->IsCustom = TRUE; + } + } + if(pSiS->HaveCustomModes) { + if(!(mymode->type & M_T_DEFAULT)) { + pSiS->IsCustom = TRUE; + } + } + } + } else { + /* CRT1 */ + if(pSiS->HaveCustomModes) { + if(!(mymode->type & M_T_DEFAULT)) { + pSiS->IsCustom = TRUE; + } + } + } + } else +#endif + { + if(vbflag & CRT2_LCD) { + if(pSiS->SiS_Pr->CP_HaveCustomData) { + for(i=0; i<7; i++) { + if(pSiS->SiS_Pr->CP_DataValid[i]) { + if((mymode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) && + (mymode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) { + if(mymode->type & M_T_BUILTIN) { + pSiS->IsCustom = TRUE; + } + } + } + } + } + } + if(vbflag & (CRT2_LCD|CRT2_VGA)) { + if(pSiS->AddedPlasmaModes) { + if(mymode->type & M_T_BUILTIN) { + pSiS->IsCustom = TRUE; + } + } + } + if((pSiS->HaveCustomModes) && (!(vbflag & CRT2_TV))) { + if(!(mymode->type & M_T_DEFAULT)) { + pSiS->IsCustom = TRUE; + } } } - /* TW: The CR3x registers are for communicating with our BIOS emulation +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); /* Unlock Registers */ +#endif + + /* The CR3x registers are for communicating with our BIOS emulation * code (native code in init.c/init301.c) or the BIOS (via VESA) */ inSISIDXREG(SISCR, 0x30, usScratchCR30); /* Bridge config */ inSISIDXREG(SISCR, 0x31, usScratchCR31); /* Bridge config */ usScratchCR32 = pSiS->newCR32; /* Bridge connection info (use our new value) */ - inSISIDXREG(SISCR, 0x33, usScratchCR33); /* CRT1 refresh rate index */ + inSISIDXREG(SISCR, 0x33, usScratchCR33); /* Refresh rate index */ if(pSiS->Chipset != PCI_CHIP_SIS300) { switch(pSiS->VGAEngine) { - case SIS_300_VGA: temp = 0x35; break; - case SIS_315_VGA: temp = 0x38; break; + case SIS_300_VGA: temp = 0x35; break; + case SIS_315_VGA: temp = 0x38; break; } } if(temp) inSISIDXREG(SISCR, temp, usScratchCR38); /* PAL-M, PAL-N selection */ + + if(pSiS->VGAEngine == SIS_315_VGA) { + inSISIDXREG(SISCR, 0x79, usScratchCR79); + } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "VBFlags=0x%x\n", pSiS->VBFlags); @@ -5716,21 +7964,32 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) usScratchCR30, usScratchCR31, usScratchCR32, usScratchCR33, temp, usScratchCR38); usScratchCR30 = 0; - usScratchCR31 &= ~0x60; /* TW: Clear VB_Drivermode & VB_OutputDisable */ -#if 0 /* TW: For future use */ + usScratchCR31 &= ~0x60; /* Clear VB_Drivermode & VB_OutputDisable */ +#if 0 /* For future use */ if( (pSiS->VBFlags & VB_LVDS) || (pSiS->VBFlags & VB_301) || - ( (pSiS->VBFlags & (VB_301B | VB_302B |VB_30xLV | VB_30xLVX)) && + ( (pSiS->VBFlags & (VB_301B | VB_302B |VB_301LV | VB_302LV)) && (!(pSiS->VBLCDFlags & VB_LCD_1400x1050)) ) ) { #endif - usScratchCR31 |= 0x04; /* TW: Set VB_NotSimuMode (not for 30xB/1400x1050?) */ + usScratchCR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */ #if 0 } #endif + if(!pSiS->AllowHotkey) { + usScratchCR31 |= 0x80; /* Disable hotkey-switch */ + } + + usScratchCR79 &= ~0x10; /* Enable Backlight control on 315/330 series */ + + SiS_SetEnableDstn(pSiS->SiS_Pr, FALSE); + SiS_SetEnableFstn(pSiS->SiS_Pr, FALSE); + switch(vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) { case CRT2_TV: if(vbflag & TV_CHSCART) { + usScratchCR30 |= 0x10; + usScratchCR38 &= ~0xC0; usScratchCR38 |= 0x04; usScratchCR31 |= 0x01; } else if(vbflag & TV_CHHDTV) { @@ -5744,7 +8003,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) usScratchCR30 |= 0x04; else if(vbflag & TV_SCART) usScratchCR30 |= 0x10; - else + else usScratchCR30 |= 0x08; /* default: SVIDEO */ if(!(vbflag & (TV_CHSCART | TV_CHHDTV))) { @@ -5764,14 +8023,19 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) usScratchCR31 &= ~0x04; /* Clear NotSimuMode */ pSiS->SiS_Pr->SiS_CHOverScan = pSiS->UseCHOverScan; - if(pSiS->OptTVSOver == 1) { + if((pSiS->OptTVSOver == 1) && (pSiS->ChrontelType == CHRONTEL_700x)) { pSiS->SiS_Pr->SiS_CHSOverScan = TRUE; } else { pSiS->SiS_Pr->SiS_CHSOverScan = FALSE; } +#ifdef SIS_CP + SIS_CP_DRIVER_CONFIG +#endif break; case CRT2_LCD: usScratchCR30 |= 0x21; /* LCD + SimuScanMode */ + SiS_SetEnableDstn(pSiS->SiS_Pr, pSiS->DSTN); + SiS_SetEnableFstn(pSiS->SiS_Pr, pSiS->FSTN); break; case CRT2_VGA: usScratchCR30 |= 0x41; /* VGA2 + SimuScanMode */ @@ -5780,36 +8044,29 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) usScratchCR30 |= 0x00; usScratchCR31 |= 0x20; /* VB_OUTPUT_DISABLE */ if(pSiS->UseVESA) { - crt1rateindex = SISSearchCRT1Rate(pScrn, mode); + crt1rateindex = SISSearchCRT1Rate(pScrn, mymode); } } - /* TW: for VESA: no DRIVERMODE, otherwise + + /* for VESA: no DRIVERMODE, otherwise * -) CRT2 will not be initialized correctly when using mode * where LCD has to scale, and * -) CRT1 will have too low rate */ - if (pSiS->UseVESA) { - usScratchCR31 &= 0x40; /* TW: Clear Drivermode */ + if(pSiS->UseVESA) { + usScratchCR31 &= ~0x40; /* Clear Drivermode */ #ifdef TWDEBUG - usScratchCR31 |= 0x40; /* DEBUG (for non-slave mode VESA) */ - crt1rateindex = SISSearchCRT1Rate(pScrn, mode); + usScratchCR31 |= 0x40; /* DEBUG (for non-slave mode VESA) */ + crt1rateindex = SISSearchCRT1Rate(pScrn, mymode); #endif } else { - usScratchCR31 |= 0x40; /* TW: Set Drivermode */ + usScratchCR31 |= 0x40; /* Set Drivermode */ if(!pSiS->IsCustom) { - crt1rateindex = SISSearchCRT1Rate(pScrn, mode); + crt1rateindex = SISSearchCRT1Rate(pScrn, mymode); } else { crt1rateindex = usScratchCR33; } } - outSISIDXREG(SISCR, 0x30, usScratchCR30); - outSISIDXREG(SISCR, 0x31, usScratchCR31); - if(temp) { - usScratchCR38 &= ~0x03; /* Clear LCDA/DualEdge bits */ - outSISIDXREG(SISCR, temp, usScratchCR38); - } - - pSiS->SiS_Pr->SiS_UseOEM = pSiS->OptUseOEM; #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { @@ -5820,28 +8077,52 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) } else { /* CRT2 */ usScratchCR33 &= 0x0f; - if(vbflag & CRT2_VGA) usScratchCR33 |= ((crt1rateindex << 4) & 0xf0); + if(vbflag & CRT2_VGA) { + usScratchCR33 |= ((crt1rateindex << 4) & 0xf0); + } } - } else { + } else +#endif +#ifdef SISMERGED + if(pSiS->MergedFB) { + usScratchCR33 = crt1rateindex & 0x0f; + if(vbflag & CRT2_VGA) { + if(!pSiS->IsCustomCRT2) { + usScratchCR33 |= (SISSearchCRT1Rate(pScrn, mymode2) << 4); + } + } + } else #endif + { if(vbflag & CRT2_VGA) { usScratchCR33 = (crt1rateindex & 0x0f) | ((crt1rateindex & 0x0f) << 4); } else { usScratchCR33 = crt1rateindex & 0x0f; } if((!(pSiS->UseVESA)) && (vbflag & CRT2_ENABLE)) { -#ifndef TWDEBUG if(pSiS->CRT1off) usScratchCR33 &= 0xf0; -#endif } -#ifdef SISDUALHEAD } -#endif + + outSISIDXREG(SISCR, 0x30, usScratchCR30); + outSISIDXREG(SISCR, 0x31, usScratchCR31); + outSISIDXREG(SISCR, 0x33, usScratchCR33); + if(pSiS->VGAEngine == SIS_315_VGA) { + usScratchCR38 &= ~0x03; /* Clear LCDA/DualEdge bits */ + outSISIDXREG(SISCR, 0x79, usScratchCR79); + } + + if(temp) { + outSISIDXREG(SISCR, temp, usScratchCR38); + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "After: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x\n", - usScratchCR30, usScratchCR31, usScratchCR33); + "After: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x, CR%02x=%02x\n", + usScratchCR30, usScratchCR31, usScratchCR33, temp, usScratchCR38); + + pSiS->SiS_Pr->SiS_UseOEM = pSiS->OptUseOEM; /* Enable TurboQueue */ SiSEnableTurboQueue(pScrn); @@ -5850,10 +8131,10 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) /* Switch on CRT1 for modes that require the bridge in SlaveMode */ inSISIDXREG(SISCR, 0x17, usScratchCR17); if(!(usScratchCR17 & 0x80)) { - orSISIDXREG(SISCR, 0x17, 0x80); - outSISIDXREG(SISSR, 0x00, 0x01); - usleep(10000); - outSISIDXREG(SISSR, 0x00, 0x03); + orSISIDXREG(SISCR, 0x17, 0x80); + outSISIDXREG(SISSR, 0x00, 0x01); + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); } } @@ -6041,7 +8322,10 @@ void SiS_SetCHTVlumaflickerfilter(ScrnInfoPtr pScrn, int val) case CHRONTEL_700x: val /= 6; if((val >= 0) && (val <= 2)) { - SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x01),0xF3); + unsigned short reg = 0; + reg = SiS_GetCH70xx(pSiS->SiS_Pr, 0x01); + reg = (reg & 0xf0) | ((reg & 0x0c) >> 2) | (val << 2); + SiS_SetCH70xx(pSiS->SiS_Pr, ((reg << 8) | 0x01)); } break; case CHRONTEL_701x: @@ -6073,7 +8357,7 @@ int SiS_GetCHTVlumaflickerfilter(ScrnInfoPtr pScrn) #endif switch(pSiS->ChrontelType) { case CHRONTEL_700x: - return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 6); + return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x03) * 6); case CHRONTEL_701x: return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 4); default: @@ -6169,7 +8453,10 @@ void SiS_SetCHTVchromaflickerfilter(ScrnInfoPtr pScrn, int val) case CHRONTEL_700x: val /= 6; if((val >= 0) && (val <= 2)) { - SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x01),0xCF); + unsigned short reg = 0; + reg = SiS_GetCH70xx(pSiS->SiS_Pr, 0x01); + reg = (reg & 0xc0) | ((reg & 0x0c) >> 2) | ((reg & 0x03) << 2) | (val << 4); + SiS_SetCH70xx(pSiS->SiS_Pr, ((reg << 8) | 0x01)); } break; case CHRONTEL_701x: @@ -6221,14 +8508,14 @@ void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val) #ifdef SISDUALHEAD if(pSiSEnt) pSiSEnt->chtvcvbscolor = pSiS->chtvcvbscolor; #endif - + if(!(pSiS->VBFlags & CRT2_TV)) return; if(!(pSiS->VBFlags & VB_CHRONTEL)) return; - + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - + switch(pSiS->ChrontelType) { case CHRONTEL_700x: if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x4003,0x00); @@ -6238,7 +8525,7 @@ void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val) if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x0002,~0x20); else SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x2002,0x00); break; - } + } } int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn) @@ -6249,8 +8536,8 @@ int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn) #endif if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { -#ifdef SISDUALHEAD - if(pSiSEnt && pSiS->DualHeadMode) +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) return (int)pSiSEnt->chtvcvbscolor; else #endif @@ -6265,9 +8552,9 @@ int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn) case CHRONTEL_701x: return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x20) >> 5) ^ 0x01); default: - return -2; + return -2; } - } + } } void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val) @@ -6281,10 +8568,10 @@ void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val) #ifdef SISDUALHEAD if(pSiSEnt) pSiSEnt->chtvtextenhance = val; #endif - + if(!(pSiS->VBFlags & CRT2_TV)) return; if(!(pSiS->VBFlags & VB_CHRONTEL)) return; - + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif @@ -6293,7 +8580,10 @@ void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val) case CHRONTEL_700x: val /= 6; if((val >= 0) && (val <= 2)) { - SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x01),0xFC); + unsigned short reg = 0; + reg = SiS_GetCH70xx(pSiS->SiS_Pr, 0x01); + reg = (reg & 0xf0) | ((reg & 0x03) << 2) | val; + SiS_SetCH70xx(pSiS->SiS_Pr, ((reg << 8) | 0x01)); } break; case CHRONTEL_701x: @@ -6302,7 +8592,7 @@ void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x03),0xF8); } break; - } + } } int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn) @@ -6325,11 +8615,11 @@ int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn) #endif switch(pSiS->ChrontelType) { case CHRONTEL_700x: - return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x03) * 6); + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 6); case CHRONTEL_701x: return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x07) * 2); default: - return -2; + return -2; } } } @@ -6362,8 +8652,9 @@ void SiS_SetCHTVcontrast(ScrnInfoPtr pScrn, int val) case CHRONTEL_701x: SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x08),0xF8); break; - } - } + } + SiS_DDC2Delay(pSiS->SiS_Pr, 1000); + } } int SiS_GetCHTVcontrast(ScrnInfoPtr pScrn) @@ -6463,8 +8754,8 @@ void SiS_SetSISTVantiflicker(ScrnInfoPtr pScrn, int val) sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - val /= 2; - if((val >= 0) && (val <= 7)) { + /* Valid values: 0=off, 1=low, 2=med, 3=high, 4=adaptive */ + if((val >= 0) && (val <= 4)) { setSISIDXREG(SISPART2,0x0A,0x8F, (val << 4)); } } @@ -6482,14 +8773,14 @@ int SiS_GetSISTVantiflicker(ScrnInfoPtr pScrn) return (int)pSiSEnt->sistvantiflicker; else #endif - return (int)pSiS->sistvantiflicker; + return (int)pSiS->sistvantiflicker; } else { unsigned char temp; #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif inSISIDXREG(SISPART2, 0x0a, temp); - return(int)(((temp & 0x70) >> 4) * 2); + return(int)((temp & 0x70) >> 4); } } @@ -6507,7 +8798,7 @@ void SiS_SetSISTVsaturation(ScrnInfoPtr pScrn, int val) if(!(pSiS->VBFlags & CRT2_TV)) return; if(!(pSiS->VBFlags & VB_SISBRIDGE)) return; - + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif @@ -6524,33 +8815,303 @@ int SiS_GetSISTVsaturation(ScrnInfoPtr pScrn) #ifdef SISDUALHEAD SISEntPtr pSiSEnt = pSiS->entityPrivate; #endif - + if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) { -#ifdef SISDUALHEAD - if(pSiSEnt && pSiS->DualHeadMode) +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) return (int)pSiSEnt->sistvsaturation; else -#endif +#endif return (int)pSiS->sistvsaturation; } else { unsigned char temp; #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); -#endif +#endif inSISIDXREG(SISPART4, 0x21, temp); return(int)((temp & 0x07) * 2); } } +void SiS_SetSISTVcolcalib(ScrnInfoPtr pScrn, int val, Bool coarse) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + int ccoarse, cfine, cbase = pSiS->sistvccbase; + unsigned char temp; + +#ifdef SISDUALHEAD + if(pSiSEnt) cbase = pSiSEnt->sistvccbase; +#endif + + if(coarse) { + pSiS->sistvcolcalibc = ccoarse = val; + cfine = pSiS->sistvcolcalibf; +#ifdef SISDUALHEAD + if(pSiSEnt) { + pSiSEnt->sistvcolcalibc = val; + cfine = pSiSEnt->sistvcolcalibf; + } +#endif + } else { + pSiS->sistvcolcalibf = cfine = val; + ccoarse = pSiS->sistvcolcalibc; +#ifdef SISDUALHEAD + if(pSiSEnt) { + pSiSEnt->sistvcolcalibf = val; + ccoarse = pSiSEnt->sistvcolcalibc; + } +#endif + } + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_SISBRIDGE)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if((cfine >= -128) && (cfine <= 127) && (ccoarse >= -120) && (ccoarse <= 120)) { + long finalcc = cbase + (((ccoarse * 256) + cfine) * 256); + + inSISIDXREG(SISPART4,0x1f,temp); + if(!(temp & 0x01)) { +#if 0 + if(pSiS->VBFlags & TV_NTSC) finalcc += 0x21ed8620; + else if(pSiS->VBFlags & TV_PALM) finalcc += ?; + else if(pSiS->VBFlags & TV_PALM) finalcc += ?; + else finalcc += 0x2a05d300; +#endif + } + setSISIDXREG(SISPART2,0x31,0x80,((finalcc >> 24) & 0x7f)); + outSISIDXREG(SISPART2,0x32,((finalcc >> 16) & 0xff)); + outSISIDXREG(SISPART2,0x33,((finalcc >> 8) & 0xff)); + outSISIDXREG(SISPART2,0x34,(finalcc & 0xff)); + } +} + +int SiS_GetSISTVcolcalib(ScrnInfoPtr pScrn, Bool coarse) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiSEnt && pSiS->DualHeadMode) + if(coarse) + return (int)pSiSEnt->sistvcolcalibc; + else + return (int)pSiSEnt->sistvcolcalibf; + else +#endif + if(coarse) + return (int)pSiS->sistvcolcalibc; + else + return (int)pSiS->sistvcolcalibf; +} + +void SiS_SetSISTVcfilter(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->sistvcfilter = val ? 1 : 0; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->sistvcfilter = pSiS->sistvcfilter; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_SISBRIDGE)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + setSISIDXREG(SISPART2,0x30,~0x10,((pSiS->sistvcfilter << 4) & 0x10)); +} + +int SiS_GetSISTVcfilter(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->sistvcfilter; + else +#endif + return (int)pSiS->sistvcfilter; + } else { + unsigned char temp; +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + inSISIDXREG(SISPART2, 0x30, temp); + return(int)((temp & 0x10) ? 1 : 0); + } +} + +void SiS_SetSISTVyfilter(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + unsigned char p35,p36,p37,p38,p48,p49,p4a,p30; + int i,j; + + pSiS->sistvyfilter = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->sistvyfilter = pSiS->sistvyfilter; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_SISBRIDGE)) return; + + p35 = pSiS->p2_35; p36 = pSiS->p2_36; + p37 = pSiS->p2_37; p38 = pSiS->p2_38; + p48 = pSiS->p2_48; p49 = pSiS->p2_49; + p4a = pSiS->p2_4a; p30 = pSiS->p2_30; +#ifdef SISDUALHEAD + if(pSiSEnt) { + p35 = pSiSEnt->p2_35; p36 = pSiSEnt->p2_36; + p37 = pSiSEnt->p2_37; p38 = pSiSEnt->p2_38; + p48 = pSiSEnt->p2_48; p49 = pSiSEnt->p2_49; + p4a = pSiSEnt->p2_4a; p30 = pSiSEnt->p2_30; + } +#endif + p30 &= 0x20; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->sistvyfilter) { + case 0: + andSISIDXREG(SISPART2,0x30,0xdf); + break; + case 1: + outSISIDXREG(SISPART2,0x35,p35); + outSISIDXREG(SISPART2,0x36,p36); + outSISIDXREG(SISPART2,0x37,p37); + outSISIDXREG(SISPART2,0x38,p38); + if(!(pSiS->VBFlags & VB_301)) { + outSISIDXREG(SISPART2,0x48,p48); + outSISIDXREG(SISPART2,0x49,p49); + outSISIDXREG(SISPART2,0x4a,p4a); + } + setSISIDXREG(SISPART2,0x30,0xdf,p30); + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + if(!(pSiS->VBFlags & (TV_PALM | TV_PALN))) { + int yindex301 = -1, yindex301B = -1; + unsigned char p3d4_34; + + inSISIDXREG(SISCR,0x34,p3d4_34); + + switch((p3d4_34 & 0x7f)) { + case 0x59: /* 320x200 */ + case 0x41: + case 0x4f: + case 0x50: /* 320x240 */ + case 0x56: + case 0x53: + yindex301 = (pSiS->VBFlags & TV_NTSC) ? 0 : 4; + break; + case 0x2f: /* 640x400 */ + case 0x5d: + case 0x5e: + case 0x2e: /* 640x480 */ + case 0x44: + case 0x62: + yindex301 = (pSiS->VBFlags & TV_NTSC) ? 1 : 5; + yindex301B = (pSiS->VBFlags & TV_NTSC) ? 0 : 4; + break; + case 0x31: /* 720x480 */ + case 0x33: + case 0x35: + case 0x32: /* 720x576 */ + case 0x34: + case 0x36: + case 0x5f: /* 768x576 */ + case 0x60: + case 0x61: + yindex301 = (pSiS->VBFlags & TV_NTSC) ? 2 : 6; + yindex301B = (pSiS->VBFlags & TV_NTSC) ? 1 : 5; + break; + case 0x51: /* 400x300 */ + case 0x57: + case 0x54: + case 0x30: /* 800x600 */ + case 0x47: + case 0x63: + yindex301 = (pSiS->VBFlags & TV_NTSC) ? 3 : 7; + yindex301B = (pSiS->VBFlags & TV_NTSC) ? 2 : 6; + break; + case 0x52: /* 512x384 */ + case 0x58: + case 0x5c: + case 0x38: /* 1024x768 */ + case 0x4a: + case 0x64: + yindex301B = (pSiS->VBFlags & TV_NTSC) ? 3 : 7; + break; + } + if(pSiS->VBFlags & VB_301) { + if(yindex301 >= 0) { + for(i=0, j=0x35; i<=3; i++, j++) { + outSISIDXREG(SISPART2,j,(SiSTVFilter301[yindex301].filter[pSiS->sistvyfilter-2][i])); + } + } + } else { + if(yindex301B >= 0) { + for(i=0, j=0x35; i<=3; i++, j++) { + outSISIDXREG(SISPART2,j,(SiSTVFilter301B[yindex301B].filter[pSiS->sistvyfilter-2][i])); + } + for(i=4, j=0x48; i<=6; i++, j++) { + outSISIDXREG(SISPART2,j,(SiSTVFilter301B[yindex301B].filter[pSiS->sistvyfilter-2][i])); + } + } + } + orSISIDXREG(SISPART2,0x30,0x20); + } + } +} + +int SiS_GetSISTVyfilter(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->sistvyfilter; + else +#endif + return (int)pSiS->sistvyfilter; +} + void SiS_SetSIS6326TVantiflicker(ScrnInfoPtr pScrn, int val) { SISPtr pSiS = SISPTR(pScrn); unsigned char tmp; - - pSiS->sis6326antiflicker = val; + + pSiS->sistvantiflicker = val; if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return; - + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif @@ -6572,7 +9133,7 @@ int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn) unsigned char tmp; if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) { - return (int)pSiS->sis6326antiflicker; + return (int)pSiS->sistvantiflicker; } #ifdef UNLOCK_ALWAYS @@ -6581,7 +9142,7 @@ int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn) tmp = SiS6326GetTVReg(pScrn,0x00); if(!(tmp & 0x04)) { - return (int)pSiS->sis6326antiflicker; + return (int)pSiS->sistvantiflicker; } else { return (int)((tmp >> 5) & 0x07); } @@ -6689,7 +9250,7 @@ void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val) #ifdef SISDUALHEAD SISEntPtr pSiSEnt = pSiS->entityPrivate; #endif - + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif @@ -6700,11 +9261,11 @@ void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val) #endif if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { - + if(pSiS->VBFlags & CRT2_TV) { - + if(pSiS->VBFlags & VB_CHRONTEL) { - + int x = pSiS->tvx; #ifdef SISDUALHEAD if(pSiSEnt && pSiS->DualHeadMode) x = pSiSEnt->tvx; @@ -6719,114 +9280,91 @@ void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val) } break; case CHRONTEL_701x: - /* TO DO */ + /* Not supported by hardware */ break; } - + } else if(pSiS->VBFlags & VB_SISBRIDGE) { - + if((val >= -32) && (val <= 32)) { - unsigned char p2_1f,p2_2b,p2_2c,p2_2d,p2_43; - const unsigned char p2_left_ntsc[8][4] = { - { 0x48, 0x63, 0x49, 0xf4 }, - { 0x45, 0x60, 0x46, 0xf1 }, - { 0x43, 0x6e, 0x44, 0xff }, - { 0x40, 0x6b, 0x41, 0xfc }, - { 0x3e, 0x69, 0x3f, 0xfa }, - { 0x3c, 0x67, 0x3d, 0xf8 }, - { 0x39, 0x64, 0x3a, 0xf5 }, - { 0x37, 0x62, 0x38, 0xf3 } - }; - const unsigned char p2_right_ntsc[8][4] = { - { 0x4b, 0x66, 0x4c, 0xf7 }, - { 0x4c, 0x67, 0x4d, 0xf8 }, - { 0x4e, 0x69, 0x4f, 0xfa }, - { 0x4f, 0x6a, 0x50, 0xfb }, - { 0x51, 0x6c, 0x52, 0xfd }, - { 0x53, 0x6e, 0x54, 0xff }, - { 0x55, 0x60, 0x56, 0xf1 }, - { 0x56, 0x61, 0x57, 0xf2 } - }; - const unsigned char p2_left_pal[8][4] = { - { 0x5b, 0x66, 0x5c, 0x87 }, - { 0x59, 0x64, 0x5a, 0x85 }, - { 0x56, 0x61, 0x57, 0x82 }, - { 0x53, 0x6e, 0x54, 0x8f }, - { 0x50, 0x6b, 0x51, 0x8c }, - { 0x4d, 0x68, 0x4e, 0x89 }, - { 0x4a, 0x65, 0x4b, 0x86 }, - { 0x49, 0x64, 0x4a, 0x85 } - }; - const unsigned char p2_right_pal[8][4] = { - { 0x5f, 0x6a, 0x60, 0x8b }, - { 0x61, 0x6c, 0x62, 0x8d }, - { 0x63, 0x6e, 0x64, 0x8f }, - { 0x65, 0x60, 0x66, 0x81 }, - { 0x66, 0x61, 0x67, 0x82 }, - { 0x68, 0x63, 0x69, 0x84 }, - { 0x69, 0x64, 0x6a, 0x85 }, - { 0x6b, 0x66, 0x6c, 0x87 } - }; - val /= 4; - p2_2d = pSiS->p2_2d; -#ifdef SISDUALHEAD - if(pSiSEnt && pSiS->DualHeadMode) p2_2d = pSiSEnt->p2_2d; -#endif - p2_2d &= 0xf0; - if(val < 0) { - val = -val; - if(val == 8) val = 7; - if(pSiS->VBFlags & TV_PAL) { - p2_1f = p2_left_pal[val][0]; - p2_2b = p2_left_pal[val][1]; - p2_2c = p2_left_pal[val][2]; - p2_2d |= (p2_left_pal[val][3] & 0x0f); - } else { - p2_1f = p2_left_ntsc[val][0]; - p2_2b = p2_left_ntsc[val][1]; - p2_2c = p2_left_ntsc[val][2]; - p2_2d |= (p2_left_ntsc[val][3] & 0x0f); - } + + unsigned char p2_1f,p2_20,p2_2b,p2_43,p3d4_34; + unsigned short temp; + int myadd2, mysub; + + p2_1f = pSiS->p2_1f; + p2_20 = pSiS->p2_20; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + p2_1f = pSiSEnt->p2_1f; + p2_20 = pSiSEnt->p2_20; + } +#endif + inSISIDXREG(SISCR,0x34,p3d4_34); + p3d4_34 &= 0x7f; + + temp = p2_1f | ((p2_20 & 0xf0) << 4); + temp += (val * 2); + + p2_1f = temp & 0xff; + p2_20 = (temp & 0xf00) >> 4; + + if((pSiS->VBFlags & (TV_NTSC | TV_PALM)) && + ((p3d4_34 == 0x64) || (p3d4_34 == 0x4a) || (p3d4_34 == 0x38))) { + temp += 1514; + myadd2 = 4; + mysub = 4; } else { - if(val == 8) val = 7; - if(pSiS->VBFlags & TV_PAL) { - p2_1f = p2_right_pal[val][0]; - p2_2b = p2_right_pal[val][1]; - p2_2c = p2_right_pal[val][2]; - p2_2d |= (p2_right_pal[val][3] & 0x0f); - } else { - p2_1f = p2_right_ntsc[val][0]; - p2_2b = p2_right_ntsc[val][1]; - p2_2c = p2_right_ntsc[val][2]; - p2_2d |= (p2_right_ntsc[val][3] & 0x0f); - } + temp += 1363; + myadd2 = 3; + if(pSiS->VBFlags & VB_301) myadd2 += 3; + mysub = 5; + } + + p2_2b = ((temp & 0xf00) >> 4) | ((p2_1f - mysub) & 0x0f); + p2_43 = p2_1f + myadd2; + +#if 0 + p2_1f += (val * 2); + if((pSiS->VBFlags & (TV_NTSC | TV_PALM)) && + ((p3d4_34 == 0x64) || (p3d4_34 == 0x4a) || (p3d4_34 == 0x38))) { + p2_2b = ((p2_1f - 4) & 0x0f) | 0x70; + p2_2c = p2_1f - 22; + p2_2d = ((p2_2c - 4) & 0x0f) | 0xe0; + p2_43 = p2_1f + 4; + } else { + p2_2b = ((p2_1f - 5) & 0x0f) | 0x60; + p2_2c = p2_1f + 1; + p2_2d = ((p2_2c - 5) & 0x0f) | (pSiS->VBFlags & TV_PAL ? 0x80 : 0xf0); + p2_43 = p2_1f + 3; + if(pSiS->VBFlags & VB_301) p2_43 += 3; } - p2_43 = p2_1f + 3; +#endif + SISWaitRetraceCRT2(pScrn); outSISIDXREG(SISPART2,0x1f,p2_1f); + setSISIDXREG(SISPART2,0x20,0x0F,p2_20); outSISIDXREG(SISPART2,0x2b,p2_2b); - outSISIDXREG(SISPART2,0x2c,p2_2c); - outSISIDXREG(SISPART2,0x2d,p2_2d); outSISIDXREG(SISPART2,0x43,p2_43); } } } - + } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { - + if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) { - + unsigned char tmp; unsigned short temp1, temp2, temp3; - + tmp = SiS6326GetTVReg(pScrn,0x00); if(tmp & 0x04) { - + temp1 = pSiS->tvx1; temp2 = pSiS->tvx2; temp3 = pSiS->tvx3; if((val >= -16) && (val <= 16)) { - if(val > 0) { + if(val > 0) { temp1 += (val * 4); temp2 += (val * 4); while((temp1 > 0x0fff) || (temp2 > 0x0fff)) { @@ -6866,11 +9404,11 @@ int SiS_GetTVxposoffset(ScrnInfoPtr pScrn) SISPtr pSiS = SISPTR(pScrn); #ifdef SISDUALHEAD SISEntPtr pSiSEnt = pSiS->entityPrivate; - - if(pSiSEnt && pSiS->DualHeadMode) + + if(pSiSEnt && pSiS->DualHeadMode) return (int)pSiSEnt->tvxpos; else -#endif +#endif return (int)pSiS->tvxpos; } @@ -6891,11 +9429,11 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val) #endif if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { - + if(pSiS->VBFlags & CRT2_TV) { - + if(pSiS->VBFlags & VB_CHRONTEL) { - + int y = pSiS->tvy; #ifdef SISDUALHEAD if(pSiSEnt && pSiS->DualHeadMode) y = pSiSEnt->tvy; @@ -6910,12 +9448,12 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val) } break; case CHRONTEL_701x: - /* TO DO */ + /* Not supported by hardware */ break; } - + } else if(pSiS->VBFlags & VB_SISBRIDGE) { - + if((val >= -32) && (val <= 32)) { char p2_01, p2_02; val /= 4; @@ -6931,7 +9469,7 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val) p2_02 += (val * 2); while((p2_01 <= 0) || (p2_02 <= 0)) { p2_01 += 2; - p2_02 += 2; + p2_02 += 2; } SISWaitRetraceCRT2(pScrn); outSISIDXREG(SISPART2,0x01,p2_01); @@ -6939,18 +9477,18 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val) } } - } + } } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { - + if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) { - + unsigned char tmp; int temp1, limit; - + tmp = SiS6326GetTVReg(pScrn,0x00); if(tmp & 0x04) { - + if((val >= -16) && (val <= 16)) { temp1 = (unsigned short)pSiS->tvy1; limit = (pSiS->SiS6326Flags & SIS6326_TVPAL) ? 625 : 525; @@ -6991,17 +9529,311 @@ int SiS_GetTVyposoffset(ScrnInfoPtr pScrn) SISPtr pSiS = SISPTR(pScrn); #ifdef SISDUALHEAD SISEntPtr pSiSEnt = pSiS->entityPrivate; - - if(pSiSEnt && pSiS->DualHeadMode) + + if(pSiSEnt && pSiS->DualHeadMode) return (int)pSiSEnt->tvypos; - else -#endif + else +#endif return (int)pSiS->tvypos; } -/* TW: Disable CRT1 for saving bandwidth. This doesn't work with VESA; - * VESA uses the bridge in SlaveMode and switching CRT1 off while the - * bridge is in SlaveMode not that clever... +void SiS_SetTVxscale(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + pSiS->tvxscale = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->tvxscale = val; +#endif + + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + + if((pSiS->VBFlags & CRT2_TV) && (pSiS->VBFlags & VB_SISBRIDGE)) { + + if((val >= -16) && (val <= 16)) { + + unsigned char p2_44,p2_45,p2_46; + int scalingfactor; + + p2_44 = pSiS->p2_44; + p2_45 = pSiS->p2_45 & 0x3f; + p2_46 = pSiS->p2_46 & 0x07; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + p2_44 = pSiSEnt->p2_44; + p2_45 = pSiSEnt->p2_45 & 0x3f; + p2_46 = pSiSEnt->p2_46 & 0x07; + } +#endif + scalingfactor = (p2_46 << 13) | ((p2_45 & 0x1f) << 8) | p2_44; + + if(val < 0) { + p2_45 &= 0xdf; + scalingfactor += ((-val) * 64); + if(scalingfactor > 0xffff) scalingfactor = 0xffff; + } else if(val > 0) { + p2_45 &= 0xdf; + scalingfactor -= (val * 64); + if(scalingfactor < 1) scalingfactor = 1; + } + + p2_44 = scalingfactor & 0xff; + p2_45 &= 0xe0; + p2_45 |= ((scalingfactor >> 8) & 0x1f); + p2_46 = ((scalingfactor >> 13) & 0x07); + + SISWaitRetraceCRT2(pScrn); + outSISIDXREG(SISPART2,0x44,p2_44); + setSISIDXREG(SISPART2,0x45,0xC0,p2_45); + if(!(pSiS->VBFlags & VB_301)) { + setSISIDXREG(SISPART2,0x46,0xF8,p2_46); + } + } + + } + + } +} + +int SiS_GetTVxscale(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->tvxscale; + else +#endif + return (int)pSiS->tvxscale; +} + +void SiS_SetTVyscale(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if(val < -4) val = -4; + if(val > 3) val = 3; + + pSiS->tvyscale = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->tvyscale = val; +#endif + + if(pSiS->VBFlags & (TV_HIVISION | TV_HIVISION_LV)) return; + + if(pSiS->VGAEngine == SIS_315_VGA || pSiS->VGAEngine == SIS_315_VGA) { + + if((pSiS->VBFlags & CRT2_TV) && (pSiS->VBFlags & VB_SISBRIDGE)) { + + int srindex = -1; + int newvde, i=0, j, temp; + int vlimit = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 259 : 309; + unsigned char p3d4_34; + + inSISIDXREG(SISCR,0x34,p3d4_34); + + switch((p3d4_34 & 0x7f)) { +#if 0 + case 0x50: /* 320x240 - hdclk mode */ + case 0x56: + case 0x53: +#endif + case 0x2e: /* 640x480 */ + case 0x44: + case 0x62: + srindex = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 0 : 21; + break; + case 0x31: /* 720x480 */ + case 0x33: + case 0x35: + case 0x32: /* 720x576 */ + case 0x34: + case 0x36: + case 0x5f: /* 768x576 */ + case 0x60: + case 0x61: + if(pSiS->VGAEngine == SIS_315_VGA) { + srindex = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 7 : 28; + } + break; +#if 0 + case 0x51: /* 400x300 - hdclk mode */ + case 0x57: + case 0x54: +#endif + case 0x30: /* 800x600 */ + case 0x47: + case 0x63: + srindex = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 14 : 35; + } + + if(srindex >= 0) { + Bool found = FALSE; + if(pSiS->tvyscale != 0) { + for(j=0; j<=1; j++) { + for(i=0; i<=6; i++) { + if(SiSTVVScale[srindex+i].sindex == pSiS->tvyscale) { + found = TRUE; + break; + } + } + if(found) break; + if(pSiS->tvyscale > 0) pSiS->tvyscale--; + else pSiS->tvyscale++; + } + } +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->tvyscale = pSiS->tvyscale; +#endif + if(pSiS->tvyscale == 0) { + unsigned char p2_0a = pSiS->p2_0a; + unsigned char p2_2f = pSiS->p2_2f; + unsigned char p2_30 = pSiS->p2_30; + unsigned char p2_46 = pSiS->p2_46; + unsigned char p2_47 = pSiS->p2_47; + unsigned char p1scaling[9], p4scaling[9]; + + for(i=0; i<9; i++) { + p1scaling[i] = pSiS->scalingp1[i]; + } + for(i=0; i<9; i++) { + p4scaling[i] = pSiS->scalingp4[i]; + } +#ifdef SISDUALHEAD + if(pSiSEnt) { + p2_0a = pSiSEnt->p2_0a; + p2_2f = pSiSEnt->p2_2f; + p2_30 = pSiSEnt->p2_30; + p2_46 = pSiSEnt->p2_46; + p2_47 = pSiSEnt->p2_47; + for(i=0; i<9; i++) { + p1scaling[i] = pSiSEnt->scalingp1[i]; + } + for(i=0; i<9; i++) { + p4scaling[i] = pSiSEnt->scalingp4[i]; + } + } +#endif + SISWaitRetraceCRT2(pScrn); + for(i=0; i<9; i++) { + outSISIDXREG(SISPART1,SiSScalingP1Regs[i],p1scaling[i]); + } + for(i=0; i<9; i++) { + outSISIDXREG(SISPART4,SiSScalingP4Regs[i],p4scaling[i]); + } + + setSISIDXREG(SISPART2,0x0a,0x7f,(p2_0a & 0x80)); + outSISIDXREG(SISPART2,0x2f,p2_2f); + setSISIDXREG(SISPART2,0x30,0x3f,(p2_30 & 0xc0)); + if(!(pSiS->VBFlags & VB_301)) { + setSISIDXREG(SISPART2,0x46,0x9f,(p2_46 & 0x60)); + outSISIDXREG(SISPART2,0x47,p2_47); + } + + } else { + + int so = (pSiS->VGAEngine == SIS_300_VGA) ? 12 : 0; + int realvde; + unsigned long calctemp; + + srindex += i; + newvde = SiSTVVScale[srindex].ScaleVDE; + realvde = SiSTVVScale[srindex].RealVDE; + + do { + inSISIDXREG(SISPART2,0x01,temp); + temp = vlimit - (temp & 0x7f); + if((temp - (((newvde >> 1) - 2) + 9)) > 0) break; + SiS_SetTVyposoffset(pScrn, pSiS->tvypos - 1); + } while(1); + + SISWaitRetraceCRT2(pScrn); + if(!(pSiS->VBFlags & VB_301)) { + temp = (newvde >> 1) - 3; + setSISIDXREG(SISPART2,0x46,0x9f,((temp & 0x0300) >> 3)); + outSISIDXREG(SISPART2,0x47,(temp & 0xff)); + } + outSISIDXREG(SISPART1,0x08,(SiSTVVScale[srindex].reg[so+0] & 0xff)); + setSISIDXREG(SISPART1,0x09,0x0f,((SiSTVVScale[srindex].reg[so+0] >> 4) & 0xf0)); + outSISIDXREG(SISPART1,0x0b,(SiSTVVScale[srindex].reg[so+1] & 0xff)); + setSISIDXREG(SISPART1,0x0c,0xf0,((SiSTVVScale[srindex].reg[so+1] >> 8) & 0x0f)); + outSISIDXREG(SISPART1,0x0d,(SiSTVVScale[srindex].reg[so+2] & 0xff)); + outSISIDXREG(SISPART1,0x0e,(SiSTVVScale[srindex].reg[so+3] & 0xff)); + setSISIDXREG(SISPART1,0x12,0xf8,((SiSTVVScale[srindex].reg[so+3] >> 8 ) & 0x07)); + outSISIDXREG(SISPART1,0x10,(SiSTVVScale[srindex].reg[so+4] & 0xff)); + setSISIDXREG(SISPART1,0x11,0x8f,((SiSTVVScale[srindex].reg[so+4] >> 4) & 0x70)); + setSISIDXREG(SISPART1,0x11,0xf0,(SiSTVVScale[srindex].reg[so+5] & 0x0f)); + + setSISIDXREG(SISPART2,0x0a,0x7f,((SiSTVVScale[srindex].reg[so+6] << 7) & 0x80)); + outSISIDXREG(SISPART2,0x2f,((newvde / 2) - 2)); + setSISIDXREG(SISPART2,0x30,0x3f,((((newvde / 2) - 2) >> 2) & 0xc0)); + + outSISIDXREG(SISPART4,0x13,(SiSTVVScale[srindex].reg[so+7] & 0xff)); + outSISIDXREG(SISPART4,0x14,(SiSTVVScale[srindex].reg[so+8] & 0xff)); + setSISIDXREG(SISPART4,0x15,0x7f,((SiSTVVScale[srindex].reg[so+8] >> 1) & 0x80)); + + outSISIDXREG(SISPART4,0x16,(SiSTVVScale[srindex].reg[so+9] & 0xff)); + setSISIDXREG(SISPART4,0x15,0x87,((SiSTVVScale[srindex].reg[so+9] >> 5) & 0x78)); + + outSISIDXREG(SISPART4,0x17,(SiSTVVScale[srindex].reg[so+10] & 0xff)); + setSISIDXREG(SISPART4,0x15,0xf8,((SiSTVVScale[srindex].reg[so+10] >> 8) & 0x07)); + + outSISIDXREG(SISPART4,0x18,(SiSTVVScale[srindex].reg[so+11] & 0xff)); + setSISIDXREG(SISPART4,0x19,0xf0,((SiSTVVScale[srindex].reg[so+11] >> 8) & 0x0f)); + + temp = 0x40; + if(realvde <= newvde) temp = 0; + else realvde -= newvde; + + calctemp = (realvde * 256 * 1024) / newvde; + if((realvde * 256 * 1024) % newvde) calctemp++; + outSISIDXREG(SISPART4,0x1b,(calctemp & 0xff)); + outSISIDXREG(SISPART4,0x1a,((calctemp >> 8) & 0xff)); + setSISIDXREG(SISPART4,0x19,0x8f,(((calctemp >> 12) & 0x30) | temp)); + } + } + + } + + } +} + +int SiS_GetTVyscale(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->tvyscale; + else +#endif + return (int)pSiS->tvyscale; +} + +/* PostSetMode: + * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA; + * VESA uses the bridge in SlaveMode and switching CRT1 off while + * the bridge is in SlaveMode not that clever... + * -) Check if overlay can be used (depending on dotclock) + * -) Check if Panel Scaler is active on LVDS for overlay re-scaling + * -) Save TV registers for further processing + * -) Apply TV settings */ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) { @@ -7012,12 +9844,15 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) unsigned char usScratchCR17; Bool flag = FALSE; Bool doit = TRUE; - int temp; + int myclock, temp; + unsigned char sr2b, sr2c, tmpreg; + float num, denum, postscalar, divider; #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1off is %d\n", pSiS->CRT1off); #endif + pSiS->CRT1isoff = pSiS->CRT1off; #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); @@ -7031,14 +9866,14 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) "VBFlags restored to %0lx\n", pSiS->VBFlags); } - /* TW: -) We can't switch off CRT1 if bridge is in SlaveMode. - * -) If we change to a SlaveMode-Mode (like 512x384), we - * need to adapt VBFlags for eg. Xv. + /* -) We can't switch off CRT1 if bridge is in SlaveMode. + * -) If we change to a SlaveMode-Mode (like 512x384), we + * need to adapt VBFlags for eg. Xv. */ #ifdef SISDUALHEAD if(!pSiS->DualHeadMode) { #endif - if(SiSBridgeIsInSlaveMode(pScrn)) { + if(SiSBridgeIsInSlaveMode(pScrn)) { doit = FALSE; temp = pSiS->VBFlags; pSiS->VBFlags &= (~VB_DISPMODE_SINGLE); @@ -7051,30 +9886,120 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) #ifdef SISDUALHEAD } #endif - if(doit) { - inSISIDXREG(SISCR, 0x17, usScratchCR17); - if(pSiS->CRT1off) { - if(usScratchCR17 & 0x80) flag = TRUE; - usScratchCR17 &= ~0x80; - } else { - if(!(usScratchCR17 & 0x80)) flag = TRUE; - usScratchCR17 |= 0x80; - } - outSISIDXREG(SISCR, 0x17, usScratchCR17); - /* TW: Reset only if status changed */ - if(flag) { - outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ - usleep(10000); - outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + + if(pSiS->VGAEngine == SIS_315_VGA) { + + if(pSiS->CRT1off) { + orSISIDXREG(SISCR,0x63,0x40); + orSISIDXREG(SISSR,0x1f,0xc0); + } else { + andSISIDXREG(SISCR,0x63,0xBF); + andSISIDXREG(SISSR,0x1f,0x3f); + } + + } else { + + if(doit) { + inSISIDXREG(SISCR, 0x17, usScratchCR17); + if(pSiS->CRT1off) { + if(usScratchCR17 & 0x80) flag = TRUE; + usScratchCR17 &= ~0x80; + } else { + if(!(usScratchCR17 & 0x80)) flag = TRUE; + usScratchCR17 |= 0x80; + } + outSISIDXREG(SISCR, 0x17, usScratchCR17); + /* Reset only if status changed */ + if(flag) { + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + } + } + + /* For some reason, sending CRT1 into power-save while in slave mode + * on Chrontel TV, makes the chrontel lose sync... TODO: Test this + * on Chrontel 7019 + */ + if((pSiS->CRT1off) && + (!((pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->VBFlags & VB_CHRONTEL) && + (pSiS->VBFlags & CRT2_TV) && + (!doit)))) { + orSISIDXREG(SISSR,0x1f,0xc0); + } else { + andSISIDXREG(SISSR,0x1f,0x3f); } } + + } + + /* Determine if the video overlay can be used */ + if(!pSiS->NoXvideo) { + inSISIDXREG(SISSR,0x2b,sr2b); + inSISIDXREG(SISSR,0x2c,sr2c); + divider = (sr2b & 0x80) ? 2.0 : 1.0; + postscalar = (sr2c & 0x80) ? + ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0 ) : + ( ((sr2c >> 5) & 0x03) + 1.0 ); + num = (sr2b & 0x7f) + 1.0; + denum = (sr2c & 0x1f) + 1.0; + myclock = (int)((14318 * (divider / postscalar) * (num / denum)) / 1000); + + pSiS->MiscFlags &= ~MISC_CRT1OVERLAY; + switch(pSiS->sishw_ext.jChipType) { + case SIS_300: + case SIS_540: + case SIS_630: + case SIS_730: + if(myclock < 150) { + pSiS->MiscFlags |= MISC_CRT1OVERLAY; + } + break; + case SIS_315H: + case SIS_315: + case SIS_315PRO: + case SIS_550: + case SIS_650: + case SIS_740: + case SIS_330: + case SIS_660: + if(myclock < 180) { + pSiS->MiscFlags |= MISC_CRT1OVERLAY; + } + break; + } + if(!(pSiS->MiscFlags & MISC_CRT1OVERLAY)) { +#ifdef SISDUALHEAD + if((!pSiS->DualHeadMode) || (pSiS->SecondHead)) +#endif + xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3, + "Current dotclock does not permit usage of video overlay on CRT1\n"); + } + } + + /* Determine if the Panel Link scaler is active */ + pSiS->MiscFlags &= ~MISC_PANELLINKSCALER; + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) { + if(pSiS->VGAEngine == SIS_300_VGA) { + inSISIDXREG(SISPART1,0x1e,tmpreg); + tmpreg &= 0x3f; + if(tmpreg) pSiS->MiscFlags |= MISC_PANELLINKSCALER; + } else { + inSISIDXREG(SISPART1,0x35,tmpreg); + tmpreg &= 0x04; + if(!tmpreg) pSiS->MiscFlags |= MISC_PANELLINKSCALER; + } + + } } - /* TW: Apply TV settings given by options + /* Apply TV settings given by options Do this even in DualHeadMode: - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1 - if this is called by SetModeCRT2, CRT2 mode has changed (duh!) - -> In both cases, the settings must be re-applied. + -> Hence, in both cases, the settings must be re-applied. */ if(pSiS->VBFlags & CRT2_TV) { int val; @@ -7089,7 +10014,7 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) int mychtvcontrast = pSiS->chtvcontrast; int mytvxpos = pSiS->tvxpos; int mytvypos = pSiS->tvypos; -#ifdef SISDUALHEAD +#ifdef SISDUALHEAD if(pSiSEnt && pSiS->DualHeadMode) { mychtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs; mychtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo; @@ -7139,10 +10064,10 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) pSiSEnt->tvx = pSiS->tvx; pSiSEnt->tvy = pSiS->tvy; } -#endif +#endif break; case CHRONTEL_701x: - /* TO DO */ + /* Not supported by hardware */ break; } if((val = mytvxpos) != 0) { @@ -7158,7 +10083,7 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) if(pSiSEnt && pSiS->DualHeadMode) { mysistvedgeenhance = pSiSEnt->sistvedgeenhance; } -#endif +#endif if((val = mysistvedgeenhance) != -1) { SiS_SetSISTVedgeenhance(pScrn, val); } @@ -7166,39 +10091,120 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) if(pSiS->VBFlags & VB_SISBRIDGE) { int mysistvantiflicker = pSiS->sistvantiflicker; int mysistvsaturation = pSiS->sistvsaturation; + int mysistvcolcalibf = pSiS->sistvcolcalibf; + int mysistvcolcalibc = pSiS->sistvcolcalibc; + int mysistvcfilter = pSiS->sistvcfilter; + int mysistvyfilter = pSiS->sistvyfilter; int mytvxpos = pSiS->tvxpos; int mytvypos = pSiS->tvypos; + int mytvxscale = pSiS->tvxscale; + int mytvyscale = pSiS->tvyscale; + int i; + unsigned long cbase; + unsigned char ctemp; #ifdef SISDUALHEAD if(pSiSEnt && pSiS->DualHeadMode) { mysistvantiflicker = pSiSEnt->sistvantiflicker; mysistvsaturation = pSiSEnt->sistvsaturation; + mysistvcolcalibf = pSiSEnt->sistvcolcalibf; + mysistvcolcalibc = pSiSEnt->sistvcolcalibc; + mysistvcfilter = pSiSEnt->sistvcfilter; + mysistvyfilter = pSiSEnt->sistvyfilter; mytvxpos = pSiSEnt->tvxpos; mytvypos = pSiSEnt->tvypos; + mytvxscale = pSiSEnt->tvxscale; + mytvyscale = pSiSEnt->tvyscale; } -#endif - /* Backup default TV position registers */ - inSISIDXREG(SISPART2,0x2d,pSiS->p2_2d); +#endif + /* Backup default TV position, scale and colcalib registers */ + inSISIDXREG(SISPART2,0x1f,pSiS->p2_1f); + inSISIDXREG(SISPART2,0x20,pSiS->p2_20); inSISIDXREG(SISPART2,0x01,pSiS->p2_01); inSISIDXREG(SISPART2,0x02,pSiS->p2_02); + inSISIDXREG(SISPART2,0x44,pSiS->p2_44); + inSISIDXREG(SISPART2,0x45,pSiS->p2_45); + if(!(pSiS->VBFlags & VB_301)) { + inSISIDXREG(SISPART2,0x46,pSiS->p2_46); + } else { + pSiS->p2_46 = 0; + } + inSISIDXREG(SISPART2,0x0a,pSiS->p2_0a); + inSISIDXREG(SISPART2,0x31,cbase); + cbase = (cbase & 0x7f) << 8; + inSISIDXREG(SISPART2,0x32,ctemp); + cbase = (cbase | ctemp) << 8; + inSISIDXREG(SISPART2,0x33,ctemp); + cbase = (cbase | ctemp) << 8; + inSISIDXREG(SISPART2,0x34,ctemp); + pSiS->sistvccbase = (cbase | ctemp); + inSISIDXREG(SISPART2,0x35,pSiS->p2_35); + inSISIDXREG(SISPART2,0x36,pSiS->p2_36); + inSISIDXREG(SISPART2,0x37,pSiS->p2_37); + inSISIDXREG(SISPART2,0x38,pSiS->p2_38); + if(!(pSiS->VBFlags & VB_301)) { + inSISIDXREG(SISPART2,0x47,pSiS->p2_47); + inSISIDXREG(SISPART2,0x48,pSiS->p2_48); + inSISIDXREG(SISPART2,0x49,pSiS->p2_49); + inSISIDXREG(SISPART2,0x4a,pSiS->p2_4a); + } + inSISIDXREG(SISPART2,0x2f,pSiS->p2_2f); + inSISIDXREG(SISPART2,0x30,pSiS->p2_30); + for(i=0; i<9; i++) { + inSISIDXREG(SISPART1,SiSScalingP1Regs[i],pSiS->scalingp1[i]); + } + for(i=0; i<9; i++) { + inSISIDXREG(SISPART4,SiSScalingP4Regs[i],pSiS->scalingp4[i]); + } #ifdef SISDUALHEAD if(pSiSEnt && pSiS->DualHeadMode) { - pSiSEnt->p2_2d = pSiS->p2_2d; - pSiSEnt->p2_01 = pSiS->p2_01; - pSiSEnt->p2_02 = pSiS->p2_02; + pSiSEnt->p2_1f = pSiS->p2_1f; pSiSEnt->p2_20 = pSiS->p2_20; + pSiSEnt->p2_01 = pSiS->p2_01; pSiSEnt->p2_02 = pSiS->p2_02; + pSiSEnt->p2_44 = pSiS->p2_44; pSiSEnt->p2_45 = pSiS->p2_45; + pSiSEnt->p2_46 = pSiS->p2_46; pSiSEnt->p2_0a = pSiS->p2_0a; + pSiSEnt->sistvccbase = pSiS->sistvccbase; + pSiSEnt->p2_35 = pSiS->p2_35; pSiSEnt->p2_36 = pSiS->p2_36; + pSiSEnt->p2_37 = pSiS->p2_37; pSiSEnt->p2_38 = pSiS->p2_38; + pSiSEnt->p2_48 = pSiS->p2_48; pSiSEnt->p2_49 = pSiS->p2_49; + pSiSEnt->p2_4a = pSiS->p2_4a; pSiSEnt->p2_2f = pSiS->p2_2f; + pSiSEnt->p2_30 = pSiS->p2_30; pSiSEnt->p2_47 = pSiS->p2_47; + for(i=0; i<9; i++) { + pSiSEnt->scalingp1[i] = pSiS->scalingp1[i]; + } + for(i=0; i<9; i++) { + pSiSEnt->scalingp4[i] = pSiS->scalingp4[i]; + } } -#endif +#endif if((val = mysistvantiflicker) != -1) { SiS_SetSISTVantiflicker(pScrn, val); } if((val = mysistvsaturation) != -1) { SiS_SetSISTVsaturation(pScrn, val); } + if((val = mysistvcfilter) != -1) { + SiS_SetSISTVcfilter(pScrn, val); + } + if((val = mysistvyfilter) != 1) { + SiS_SetSISTVyfilter(pScrn, val); + } + if((val = mysistvcolcalibc) != 0) { + SiS_SetSISTVcolcalib(pScrn, val, TRUE); + } + if((val = mysistvcolcalibf) != 0) { + SiS_SetSISTVcolcalib(pScrn, val, FALSE); + } if((val = mytvxpos) != 0) { SiS_SetTVxposoffset(pScrn, val); } if((val = mytvypos) != 0) { - SiS_SetTVyposoffset(pScrn, val); - } + SiS_SetTVyposoffset(pScrn, val); + } + if((val = mytvxscale) != 0) { + SiS_SetTVxscale(pScrn, val); + } + if((val = mytvyscale) != 0) { + SiS_SetTVyscale(pScrn, val); + } } } @@ -7227,7 +10233,7 @@ void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) pSiS->tvy1 = SiS6326GetTVReg(pScrn,0x11); pSiS->tvy1 |= ((SiS6326GetTVReg(pScrn,0x13) & 0x30) << 4); - /* TW: Handle TVPosOffset options (BEFORE switching on TV) */ + /* Handle TVPosOffset options (BEFORE switching on TV) */ if((val = pSiS->tvxpos) != 0) { SiS_SetTVxposoffset(pScrn, val); } @@ -7235,8 +10241,8 @@ void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) SiS_SetTVyposoffset(pScrn, val); } - /* TW: Switch on TV output. This is rather complicated, but - * if we don't do it, TV output will flicker terribly. + /* Switch on TV output. This is rather complicated, but + * if we don't do it, TV output will flicker terribly. */ if(pSiS->SiS6326Flags & SIS6326_TVON) { orSISIDXREG(SISSR, 0x01, 0x20); @@ -7265,8 +10271,8 @@ void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) tmp = SiS6326GetTVReg(pScrn,0x00); if(!(tmp & 0x04)) return; - /* TW: Apply TV settings given by options */ - if((val = pSiS->sis6326antiflicker) != -1) { + /* Apply TV settings given by options */ + if((val = pSiS->sistvantiflicker) != -1) { SiS_SetSIS6326TVantiflicker(pScrn, val); } if((val = pSiS->sis6326enableyfilter) != -1) { @@ -7296,7 +10302,7 @@ SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn) } } -/* TW: Build a list of the VESA modes the BIOS reports as valid */ +/* Build a list of the VESA modes the BIOS reports as valid */ static void SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe) { @@ -7331,7 +10337,7 @@ SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe) } } -/* TW: Calc VESA mode from given resolution/depth */ +/* Calc VESA mode from given resolution/depth */ static UShort SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) { @@ -7353,6 +10359,16 @@ SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) mode->HDisplay, mode->VDisplay, pScrn->bitsPerPixel); switch(mode->HDisplay) { + case 320: + if(mode->VDisplay == 200) + ModeIndex = VESAModeIndex_320x200[i]; + else if(mode->VDisplay == 240) + ModeIndex = VESAModeIndex_320x240[i]; + break; + case 400: + if(mode->VDisplay == 300) + ModeIndex = VESAModeIndex_400x300[i]; + break; case 512: if(mode->VDisplay == 384) ModeIndex = VESAModeIndex_512x384[i]; @@ -7360,6 +10376,8 @@ SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) case 640: if(mode->VDisplay == 480) ModeIndex = VESAModeIndex_640x480[i]; + else if(mode->VDisplay == 400) + ModeIndex = VESAModeIndex_640x400[i]; break; case 800: if(mode->VDisplay == 600) @@ -7390,7 +10408,619 @@ SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) return(ModeIndex); } -/* TW: Calculate the vertical refresh rate from a mode */ +USHORT +SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN havecustommodes) +{ + SISPtr pSiS = SISPTR(pScrn); + UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; + UShort ModeIndex = 0; + + if((havecustommodes) && (!(mode->type & M_T_DEFAULT))) + return 0xfe; + + switch(mode->HDisplay) + { + case 320: + if(mode->VDisplay == 200) { + ModeIndex = ModeIndex_320x200[i]; + } else if(mode->VDisplay == 240) { + if(pSiS->FSTN) ModeIndex = ModeIndex_320x240_FSTN[i]; + else ModeIndex = ModeIndex_320x240[i]; + } + break; + case 400: + if(mode->VDisplay == 300) { + ModeIndex = ModeIndex_400x300[i]; + } + break; + case 512: + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 720: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_720x480[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_720x576[i]; + } + break; + case 768: + if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_768x576[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } else if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_800x480[i]; + } + break; + case 848: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_848x480[i]; + } + break; + case 856: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_856x480[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_1024x576[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_1024x600[i]; + } + } + break; + case 1152: + if(mode->VDisplay == 864) { + ModeIndex = ModeIndex_1152x864[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1152x768[i]; + } + } + break; + case 1280: + if(mode->VDisplay == 960) { + ModeIndex = ModeIndex_1280x960[i]; + } else if (mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } else if (mode->VDisplay == 720) { + ModeIndex = ModeIndex_1280x720[i]; + } else if (mode->VDisplay == 768) { + if(pSiS->VGAEngine == SIS_300_VGA) { + ModeIndex = ModeIndex_300_1280x768[i]; + } else { + ModeIndex = ModeIndex_310_1280x768[i]; + } + } + break; + case 1360: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1360x768[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 1024) { + ModeIndex = ModeIndex_300_1360x1024[i]; + } + } + break; + case 1400: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(mode->VDisplay == 1050) { + ModeIndex = ModeIndex_1400x1050[i]; + } + } + break; + case 1600: + if(mode->VDisplay == 1200) { + ModeIndex = ModeIndex_1600x1200[i]; + } + break; + case 1920: + if(mode->VDisplay == 1440) { + ModeIndex = ModeIndex_1920x1440[i]; + } + break; + case 2048: + if(mode->VDisplay == 1536) { + if(pSiS->VGAEngine == SIS_300_VGA) { + ModeIndex = ModeIndex_300_2048x1536[i]; + } else { + ModeIndex = ModeIndex_310_2048x1536[i]; + } + } + break; + } + + return(ModeIndex); +} + +USHORT +SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN havecustommodes) +{ + SISPtr pSiS = SISPTR(pScrn); + UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; + UShort ModeIndex = 0; + int j; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "Inside CheckCalcModeIndex (VBFlags %x, mode %dx%d)\n", + VBFlags,mode->HDisplay, mode->VDisplay); +#endif + + if(VBFlags & CRT2_LCD) { + + if(pSiS->SiS_Pr->CP_HaveCustomData) { + for(j=0; j<7; j++) { + if((pSiS->SiS_Pr->CP_DataValid[j]) && + (mode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[j]) && + (mode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[j]) && + (mode->type & M_T_BUILTIN)) + return 0xfe; + } + } + + if((pSiS->AddedPlasmaModes) && (mode->type & M_T_BUILTIN)) + return 0xfe; + + if((havecustommodes) && (!(mode->type & M_T_DEFAULT))) + return 0xfe; + + if( ((mode->HDisplay <= pSiS->LCDwidth) && + (mode->VDisplay <= pSiS->LCDheight)) || + ((pSiS->SiS_Pr->SiS_CustomT == CUT_PANEL848) && + (((mode->HDisplay == 1360) && (mode->HDisplay == 768)) || + ((mode->HDisplay == 1024) && (mode->HDisplay == 768)) || + ((mode->HDisplay == 800) && (mode->HDisplay == 600)))) ) { + + if(VBFlags & (VB_LVDS | VB_30xBDH)) { /* LCD on Panel link (LVDS, 301BDH) */ + + switch(mode->HDisplay) + { + case 320: + if(pSiS->SiS_Pr->SiS_CustomT != CUT_PANEL848) { + if(mode->VDisplay == 200) { + ModeIndex = ModeIndex_320x200[i]; + } else if(mode->VDisplay == 240) { + if(!pSiS->FSTN) { + ModeIndex = ModeIndex_320x240[i]; + } else if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_320x240_FSTN[i]; + } + } + } + break; + case 400: + if(pSiS->SiS_Pr->SiS_CustomT != CUT_PANEL848) { + if(mode->VDisplay == 300) { + ModeIndex = ModeIndex_400x300[i]; + } + } + break; + case 512: + if(pSiS->SiS_Pr->SiS_CustomT != CUT_PANEL848) { + if(mode->VDisplay == 384) { + if(pSiS->LCDwidth != 1024 || pSiS->LCDheight != 600) { /* not supported on 1024x600 panels */ + ModeIndex = ModeIndex_512x384[i]; + } + } + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + if(pSiS->SiS_Pr->SiS_CustomT != CUT_PANEL848) { + ModeIndex = ModeIndex_640x400[i]; + } + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } + break; + case 848: + if(mode->VDisplay == 480) { + if(pSiS->SiS_Pr->SiS_CustomT == CUT_PANEL848) { + ModeIndex = ModeIndex_848x480[i]; + } + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 600) { + if(pSiS->LCDheight == 600) { + ModeIndex = ModeIndex_1024x600[i]; + } + } + } + break; + case 1152: + if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 768) { + if(pSiS->LCDheight == 768) { + ModeIndex = ModeIndex_1152x768[i]; + } + } + } + break; + case 1280: + if(mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->LCDheight == 768) { + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_310_1280x768[i]; + } + } + } + break; + case 1360: + if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->SiS_Pr->SiS_CustomT == CUT_BARCO1366) { + if(mode->VDisplay == 1024) { + ModeIndex = ModeIndex_300_1360x1024[i]; + } + } + } + if(mode->VDisplay == 768) { + if(pSiS->SiS_Pr->SiS_CustomT == CUT_PANEL848) { + ModeIndex = ModeIndex_1360x768[i]; + } + } + break; + case 1400: + if(mode->VDisplay == 1050) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1400x1050[i]; + } + } + break; + case 1600: + if(mode->VDisplay == 1200) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1600x1200[i]; + } + } + break; + } + + } else { /* LCD on 301(B/LV) */ + + switch(mode->HDisplay) + { + case 320: + if(mode->VDisplay == 200) { + ModeIndex = ModeIndex_320x200[i]; + } else if(mode->VDisplay == 240) { + ModeIndex = ModeIndex_320x240[i]; + } + break; + case 400: + if(mode->VDisplay == 300) { + ModeIndex = ModeIndex_400x300[i]; + } + break; + case 512: + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } + break; + case 1280: + if(mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } else if(mode->VDisplay == 768) { + if((pSiS->LCDheight != 1050) && (pSiS->LCDheight != 960)) { + if(pSiS->VGAEngine == SIS_300_VGA) { + ModeIndex = ModeIndex_300_1280x768[i]; + } else { + ModeIndex = ModeIndex_310_1280x768[i]; + } + } + } else if(mode->VDisplay == 960) { + if((pSiS->LCDheight != 1050) && (pSiS->LCDheight != 768)) { + ModeIndex = ModeIndex_1280x960[i]; + } + } + break; + case 1400: + if(VBFlags & (VB_302B | VB_302LV)) { + if(mode->VDisplay == 1050) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1400x1050[i]; + } + } + } + break; + case 1600: + if(VBFlags & (VB_302B | VB_302LV)) { + if(mode->VDisplay == 1200) { + ModeIndex = ModeIndex_1600x1200[i]; + } + } + break; + } + + } + + } + + } else if(VBFlags & CRT2_TV) { + + if(VBFlags & VB_CHRONTEL) { /* TV on Chrontel */ + + switch(mode->HDisplay) + { + case 512: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1024x768[i]; + } + } + break; + } + + } else { /* TV on 301(B/LV) */ + + switch(mode->HDisplay) + { + case 320: /* TEST */ + if(mode->VDisplay == 200) { + ModeIndex = ModeIndex_320x200[i]; + } else if(mode->VDisplay == 240) { + ModeIndex = ModeIndex_320x240[i]; + } + break; + case 400: /* TEST */ + if(mode->VDisplay == 300) { + ModeIndex = ModeIndex_400x300[i]; + } + break; + case 512: + if(mode->VDisplay == 384) { + if((VBFlags & TV_PAL) && (!(VBFlags & TV_PALM))) + ModeIndex = ModeIndex_512x384[i]; + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 720: + if(!(VBFlags & (TV_HIVISION | TV_HIVISION_LV))) { + if(mode->VDisplay == 480) { + if((VBFlags & TV_NTSC) || (VBFlags & TV_PALM)) + ModeIndex = ModeIndex_720x480[i]; + } else if(mode->VDisplay == 576) { + if((VBFlags & TV_PAL) && (!(VBFlags & TV_PALM))) + ModeIndex = ModeIndex_720x576[i]; + } + } + break; + case 768: + if(!(VBFlags & (TV_HIVISION | TV_HIVISION_LV))) { + if(mode->VDisplay == 576) { + if((VBFlags & TV_PAL) && (!(VBFlags & TV_PALM))) + ModeIndex = ModeIndex_768x576[i]; + } + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } else if(VBFlags & (TV_HIVISION | TV_HIVISION_LV)) { + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_1024x576[i]; + } + } + break; + case 1024: + if(mode->VDisplay == 768) { + if(VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) { + ModeIndex = ModeIndex_1024x768[i]; + } + } else if(VBFlags & (TV_HIVISION | TV_HIVISION_LV)) { + if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_1024x576[i]; + } + } + break; + case 1280: + if(VBFlags & (TV_HIVISION | TV_HIVISION_LV)) { + if(mode->VDisplay == 720) { + ModeIndex = ModeIndex_1280x720[i]; + } if(mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } + } + break; + } + + } + + } else if(VBFlags & CRT2_VGA) { /* CRT2 is VGA2 */ + + if((pSiS->AddedPlasmaModes) && (mode->type & M_T_BUILTIN)) + return 0xfe; + + if((havecustommodes) && (!(mode->type & M_T_DEFAULT))) + return 0xfe; + + switch(mode->HDisplay) + { + case 320: + if(mode->VDisplay == 200) { + ModeIndex = ModeIndex_320x200[i]; + } else if(mode->VDisplay == 240) { + ModeIndex = ModeIndex_320x240[i]; + } + break; + case 400: + if(mode->VDisplay == 300) { + ModeIndex = ModeIndex_400x300[i]; + } + break; + case 512: + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 720: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_720x480[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_720x576[i]; + } + break; + case 768: + if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_768x576[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } else if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_800x480[i]; + } + break; + case 848: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_848x480[i]; + } + break; + case 856: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_856x480[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_1024x576[i]; + } + break; + case 1152: + if(mode->VDisplay == 864) { + ModeIndex = ModeIndex_1152x864[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1152x768[i]; + } + } + break; + case 1280: + if (mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } else if (mode->VDisplay == 720) { + ModeIndex = ModeIndex_1280x720[i]; + } else if (mode->VDisplay == 960) { + ModeIndex = ModeIndex_1280x960[i]; + } else if (mode->VDisplay == 768) { + if(pSiS->VGAEngine == SIS_300_VGA) { + ModeIndex = ModeIndex_300_1280x768[i]; + } else { + ModeIndex = ModeIndex_310_1280x768[i]; + } + } + break; + case 1360: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1360x768[i]; + } + break; + case 1400: + if(mode->VDisplay == 1050) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1400x1050[i]; + } + } + break; + case 1600: + if(mode->VDisplay == 1200) { + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & (VB_301B|VB_302B)) { + ModeIndex = ModeIndex_1600x1200[i]; + } + } + } + break; + } + + } else { /* CRT1 only, no CRT2 */ + + ModeIndex = SiS_CalcModeIndex(pScrn, mode, havecustommodes); + + } + + return(ModeIndex); +} + +/* Calculate the vertical refresh rate from a mode */ int SiSCalcVRate(DisplayModePtr mode) { @@ -7423,10 +11053,10 @@ SiSCalcVRate(DisplayModePtr mode) return((int)(refresh)); } -/* TW: Calculate CR33 (rate index) for CRT1. - * Calculation is done using currentmode, therefore it is - * recommended to set VertRefresh and HorizSync to correct - * values in config file. +/* Calculate CR33 (rate index) for CRT1. + * Calculation is done using currentmode, therefore it is + * recommended to set VertRefresh and HorizSync to correct + * values in config file. */ unsigned char SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode) @@ -7462,8 +11092,8 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode) } #ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh); -#endif + xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh); +#endif /* We need the REAL refresh rate here */ if(mode->Flags & V_INTERLACE) @@ -7471,8 +11101,8 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode) /* Do not multiply by 2 when DBLSCAN! */ -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh); +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh); #endif index = 0; @@ -7491,6 +11121,9 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode) index = sisx_vrate[i - 1].idx; } break; + } else if((irefresh - sisx_vrate[i].refresh) <= 2) { + index = sisx_vrate[i].idx; + break; } } } @@ -7499,7 +11132,7 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode) if(index > 0) return index; else { - /* TW: Default Rate index */ + /* Default Rate index */ if(xres == 800 || xres == 1024 || xres == 1280) return 0x02; else return 0x01; } @@ -7514,6 +11147,11 @@ SISWaitRetraceCRT1(ScrnInfoPtr pScrn) inSISIDXREG(SISCR,0x17,temp); if(!(temp & 0x80)) return; + + if(pSiS->VGAEngine == SIS_315_VGA) { + inSISIDXREG(SISSR,0x1f,temp); + if(temp & 0xc0) return; + } watchdog = 65536; while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog); @@ -7555,26 +11193,62 @@ static void SISWaitVBRetrace(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { #ifdef SISDUALHEAD - if(pSiS->DualHeadMode) { - if(pSiS->SecondHead) + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) SISWaitRetraceCRT1(pScrn); - else + else SISWaitRetraceCRT2(pScrn); - } else { + } else { #endif - if(pSiS->VBFlags & DISPTYPE_DISP1) { + if(pSiS->VBFlags & DISPTYPE_DISP1) { SISWaitRetraceCRT1(pScrn); - } - if(pSiS->VBFlags & DISPTYPE_DISP2) { + } + if(pSiS->VBFlags & DISPTYPE_DISP2) { if(!(SiSBridgeIsInSlaveMode(pScrn))) { SISWaitRetraceCRT2(pScrn); } - } + } #ifdef SISDUALHEAD - } + } #endif + } else { + SISWaitRetraceCRT1(pScrn); + } +} + +#define MODEID_OFF 0x449 + +unsigned char +SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id) +{ + return(SiS_GetSetBIOSScratch(pScrn, MODEID_OFF, id)); +} + +unsigned char +SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value) +{ + unsigned char ret; + unsigned char *base; + + base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000); + if(!base) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(Could not map BIOS scratch area)\n"); + return 0; + } + + ret = *(base + offset); + + /* value != 0xff means: set register */ + if (value != 0xff) + *(base + offset) = value; + + xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000); + + return ret; } void diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h new file mode 100644 index 000000000..b987c8876 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h @@ -0,0 +1,991 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h,v 1.14 2003/08/07 12:52:23 twini Exp $ */ +/* + * Global data and definitions + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + */ + +/* Mode numbers for 300/315/330 series */ +const UShort ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; +const UShort ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53}; +const UShort ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */ +const UShort ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54}; +const UShort ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c}; +const UShort ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e}; +const UShort ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62}; +const UShort ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35}; +const UShort ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36}; +const UShort ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61}; +const UShort ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76}; +const UShort ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63}; +const UShort ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e}; +const UShort ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45}; +const UShort ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64}; +const UShort ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77}; +const UShort ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */ +const UShort ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65}; +const UShort ModeIndex_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e}; +const UShort ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */ +const UShort ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b}; +const UShort ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b}; +const UShort ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25}; +const UShort ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78}; +const UShort ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e}; +const UShort ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */ +const UShort ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */ +const UShort ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66}; +const UShort ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b}; +const UShort ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00}; +const UShort ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e}; + +/* VESA */ +/* The following is included because there are BIOSes out there that + * report incomplete mode lists. These are 630 BIOS versions <2.01.2x + * + * -) VBE 3.0 on SiS300 and 315 series do not support 24 fpp modes + * -) Only SiS315 series support 1920x1440x32 + */ + /* 8 16 (24) 32 */ +static const UShort VESAModeIndex_320x200[] = {0x138, 0x10e, 0x000, 0x000}; +static const UShort VESAModeIndex_320x240[] = {0x132, 0x135, 0x000, 0x000}; +static const UShort VESAModeIndex_400x300[] = {0x133, 0x136, 0x000, 0x000}; +static const UShort VESAModeIndex_512x384[] = {0x134, 0x137, 0x000, 0x000}; +static const UShort VESAModeIndex_640x400[] = {0x100, 0x139, 0x000, 0x000}; +static const UShort VESAModeIndex_640x480[] = {0x101, 0x111, 0x000, 0x13a}; +static const UShort VESAModeIndex_800x600[] = {0x103, 0x114, 0x000, 0x13b}; +static const UShort VESAModeIndex_1024x768[] = {0x105, 0x117, 0x000, 0x13c}; +static const UShort VESAModeIndex_1280x1024[] = {0x107, 0x11a, 0x000, 0x13d}; +static const UShort VESAModeIndex_1600x1200[] = {0x130, 0x131, 0x000, 0x13e}; +static const UShort VESAModeIndex_1920x1440[] = {0x13f, 0x140, 0x000, 0x141}; + +/* For calculating refresh rate index (CR33) */ +static const struct _sis_vrate { + CARD16 idx; + CARD16 xres; + CARD16 yres; + CARD16 refresh; + BOOLEAN SiS730valid32bpp; +} sisx_vrate[] = { + {1, 320, 200, 70, TRUE}, + {1, 320, 240, 60, TRUE}, + {1, 400, 300, 60, TRUE}, + {1, 512, 384, 60, TRUE}, + {1, 640, 400, 72, TRUE}, + {1, 640, 480, 60, TRUE}, {2, 640, 480, 72, TRUE}, {3, 640, 480, 75, TRUE}, + {4, 640, 480, 85, TRUE}, {5, 640, 480, 100, TRUE}, {6, 640, 480, 120, TRUE}, + {7, 640, 480, 160, TRUE}, {8, 640, 480, 200, TRUE}, + {1, 720, 480, 60, TRUE}, + {1, 720, 576, 58, TRUE}, + {1, 768, 576, 58, TRUE}, + {1, 800, 480, 60, TRUE}, {2, 800, 480, 75, TRUE}, {3, 800, 480, 85, TRUE}, + {1, 800, 600, 56, TRUE}, {2, 800, 600, 60, TRUE}, {3, 800, 600, 72, TRUE}, + {4, 800, 600, 75, TRUE}, {5, 800, 600, 85, TRUE}, {6, 800, 600, 105, TRUE}, + {7, 800, 600, 120, TRUE}, {8, 800, 600, 160, TRUE}, + {1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE}, + {1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE}, + {1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE}, + {1, 1024, 600, 60, TRUE}, + {1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE}, + {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE}, + {7, 1024, 768, 120, TRUE}, + {1, 1152, 768, 60, TRUE}, + {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, TRUE}, + {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE}, + {1, 1280, 768, 60, TRUE}, + {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE}, + {1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE}, + {4, 1280, 1024, 85, TRUE}, + {1, 1360, 768, 60, TRUE}, + {1, 1400, 1050, 60, TRUE}, {2, 1400, 1050, 75, TRUE}, + {1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE}, + {4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE}, + {7, 1600, 1200, 120, TRUE}, + {1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE}, + {4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE}, + {1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE}, + {4, 2048, 1536, 75, TRUE}, {5, 2048, 1536, 85, TRUE}, + {0, 0, 0, 0, FALSE} +}; + +/* Some 300-series laptops have a badly designed BIOS and make it + * impossible to detect the correct panel delay compensation. This + * table used to detect such machines by their PCI subsystem IDs; + * however, I don't know how reliable this method is. (With Asus + * machines, it is to general, ASUS uses the same ID for different + * boxes) + */ +static const pdctable mypdctable[] = { + { 0x1071, 0x7522, 32, "Mitac", "7521T" }, + { 0, 0, 0, "" , "" } +}; + +static const chswtable mychswtable[] = { + { 0x1631, 0x1002, "Mitachi", "0x1002" }, + { 0x1071, 0x7521, "Mitac" , "7521P" }, + { 0, 0, "" , "" } +}; + +const customttable mycustomttable[] = { + { SIS_630, "2.00.07", "09/27/2002-13:38:25", + 0x3240A8, + { 0x220, 0x227, 0x228, 0x229, 0x0ee }, + { 0x01, 0xe3, 0x9a, 0x6a, 0xef }, + 0x1039, 0x6300, + "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO1366" + }, + { SIS_630, "2.00.07", "09/27/2002-13:38:25", + 0x323FBD, + { 0x220, 0x227, 0x228, 0x229, 0x0ee }, + { 0x00, 0x5a, 0x64, 0x41, 0xef }, + 0x1039, 0x6300, + "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO1024" + }, + { SIS_650, "", "", + 0, + { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + 0x0e11, 0x083c, + "Compaq", "Presario 3045US", CUT_COMPAQ12802, "COMPAQ1280" + }, + { SIS_650, "", "", + 0, + { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + 0x1558, 0x0287, + "Clevo", "L285/L287", CUT_CLEVO1024, "CLEVO1024" + }, + { 4321, "", "", /* This is hopefully NEVER autodetected */ + 0, + { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + 0, 0, + "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480" + }, + { 0, "", "", + 0, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + 0, 0, + "", "", CUT_NONE, "" + } +}; + +/* Our TV modes for the 6326. The data in these structures + * is mainly correct, but since we use our private CR and + * clock values anyway, small errors do no matter. + */ +static DisplayModeRec SiS6326PAL800x600Mode = { + NULL, NULL, /* prev, next */ + "PAL800x600", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 36000, /* Clock frequency */ + 800, /* HDisplay */ + 848, /* HSyncStart */ + 912, /* HSyncEnd */ + 1008, /* HTotal */ + 0, /* HSkew */ + 600, /* VDisplay */ + 600, /* VSyncStart */ + 602, /* VSyncEnd */ + 625, /* VTotal */ + 0, /* VScan */ + V_PHSYNC | V_PVSYNC, /* Flags */ + -1, /* ClockIndex */ + 36000, /* SynthClock */ + 800, /* CRTC HDisplay */ + 808, /* CRTC HBlankStart */ + 848, /* CRTC HSyncStart */ + 912, /* CRTC HSyncEnd */ + 1008, /* CRTC HBlankEnd */ + 1008, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 600, /* CRTC VDisplay */ + 600, /* CRTC VBlankStart */ + 600, /* CRTC VSyncStart */ + 602, /* CRTC VSyncEnd */ + 625, /* CRTC VBlankEnd */ + 625, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +/* Due to the scaling method this mode uses, the vertical data here + * does not match the CR data. But this does not matter, we use our + * private CR data anyway. + */ +static DisplayModeRec SiS6326PAL800x600UMode = { + NULL, /* prev */ + &SiS6326PAL800x600Mode, /* next */ + "PAL800x600U", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 37120, /* Clock frequency */ + 800, /* HDisplay */ + 872, /* HSyncStart */ + 984, /* HSyncEnd */ + 1088, /* HTotal */ + 0, /* HSkew */ + 600, /* VDisplay (548 due to scaling) */ + 600, /* VSyncStart (584) */ + 602, /* VSyncEnd (586) */ + 625, /* VTotal */ + 0, /* VScan */ + V_PHSYNC | V_PVSYNC, /* Flags */ + -1, /* ClockIndex */ + 37120, /* SynthClock */ + 800, /* CRTC HDisplay */ + 808, /* CRTC HBlankStart */ + 872, /* CRTC HSyncStart */ + 984, /* CRTC HSyncEnd */ + 1024, /* CRTC HBlankEnd */ + 1088, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 600, /* CRTC VDisplay (548 due to scaling) */ + 600, /* CRTC VBlankStart (600) */ + 600, /* CRTC VSyncStart (584) */ + 602, /* CRTC VSyncEnd (586) */ + 625, /* CRTC VBlankEnd */ + 625, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +static DisplayModeRec SiS6326PAL720x540Mode = { + NULL, /* prev */ + &SiS6326PAL800x600UMode, /* next */ + "PAL720x540", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 36000, /* Clock frequency */ + 720, /* HDisplay */ + 816, /* HSyncStart */ + 920, /* HSyncEnd */ + 1008, /* HTotal */ + 0, /* HSkew */ + 540, /* VDisplay */ + 578, /* VSyncStart */ + 580, /* VSyncEnd */ + 625, /* VTotal */ + 0, /* VScan */ + V_PHSYNC | V_PVSYNC, /* Flags */ + -1, /* ClockIndex */ + 36000, /* SynthClock */ + 720, /* CRTC HDisplay */ + 736, /* CRTC HBlankStart */ + 816, /* CRTC HSyncStart */ + 920, /* CRTC HSyncEnd */ + 1008, /* CRTC HBlankEnd */ + 1008, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 540, /* CRTC VDisplay */ + 577, /* CRTC VBlankStart */ + 578, /* CRTC VSyncStart */ + 580, /* CRTC VSyncEnd */ + 625, /* CRTC VBlankEnd */ + 625, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +static DisplayModeRec SiS6326PAL640x480Mode = { + NULL, /* prev */ + &SiS6326PAL720x540Mode, /* next */ + "PAL640x480", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 36000, /* Clock frequency */ + 640, /* HDisplay */ + 768, /* HSyncStart */ + 920, /* HSyncEnd */ + 1008, /* HTotal */ + 0, /* HSkew */ + 480, /* VDisplay */ + 532, /* VSyncStart */ + 534, /* VSyncEnd */ + 625, /* VTotal */ + 0, /* VScan */ + V_NHSYNC | V_NVSYNC, /* Flags */ + -1, /* ClockIndex */ + 36000, /* SynthClock */ + 640, /* CRTC HDisplay */ + 648, /* CRTC HBlankStart */ + 768, /* CRTC HSyncStart */ + 920, /* CRTC HSyncEnd */ + 944, /* CRTC HBlankEnd */ + 1008, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 480, /* CRTC VDisplay */ + 481, /* CRTC VBlankStart */ + 532, /* CRTC VSyncStart */ + 534, /* CRTC VSyncEnd */ + 561, /* CRTC VBlankEnd */ + 625, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +static DisplayModeRec SiS6326NTSC640x480Mode = { + NULL, NULL, /* prev, next */ + "NTSC640x480", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 27000, /* Clock frequency */ + 640, /* HDisplay */ + 664, /* HSyncStart */ + 760, /* HSyncEnd */ + 800, /* HTotal */ + 0, /* HSkew */ + 480, /* VDisplay */ + 489, /* VSyncStart */ + 491, /* VSyncEnd */ + 525, /* VTotal */ + 0, /* VScan */ + V_NHSYNC | V_NVSYNC, /* Flags */ + -1, /* ClockIndex */ + 27000, /* SynthClock */ + 640, /* CRTC HDisplay */ + 648, /* CRTC HBlankStart */ + 664, /* CRTC HSyncStart */ + 760, /* CRTC HSyncEnd */ + 792, /* CRTC HBlankEnd */ + 800, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 480, /* CRTC VDisplay */ + 488, /* CRTC VBlankStart */ + 489, /* CRTC VSyncStart */ + 491, /* CRTC VSyncEnd */ + 517, /* CRTC VBlankEnd */ + 525, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +/* Due to the scaling method this mode uses, the vertical data here + * does not match the CR data. But this does not matter, we use our + * private CR data anyway. + */ +static DisplayModeRec SiS6326NTSC640x480UMode = { + NULL, /* prev */ + &SiS6326NTSC640x480Mode, /* next */ + "NTSC640x480U", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 32215, /* Clock frequency */ + 640, /* HDisplay */ + 696, /* HSyncStart */ + 840, /* HSyncEnd */ + 856, /* HTotal */ + 0, /* HSkew */ + 480, /* VDisplay (439 due to scaling) */ + 489, /* VSyncStart (473) */ + 491, /* VSyncEnd (475) */ + 525, /* VTotal */ + 0, /* VScan */ + V_NHSYNC | V_NVSYNC, /* Flags */ + -1, /* ClockIndex */ + 32215, /* SynthClock */ + 640, /* CRTC HDisplay */ + 656, /* CRTC HBlankStart */ + 696, /* CRTC HSyncStart */ + 840, /* CRTC HSyncEnd */ + 856, /* CRTC HBlankEnd */ + 856, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 480, /* CRTC VDisplay */ + 488, /* CRTC VBlankStart */ + 489, /* CRTC VSyncStart */ + 491, /* CRTC VSyncEnd */ + 517, /* CRTC VBlankEnd */ + 525, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + + +static DisplayModeRec SiS6326NTSC640x400Mode = { + NULL, /* prev */ + &SiS6326NTSC640x480UMode, /* next */ + "NTSC640x400", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 27000, /* Clock frequency */ + 640, /* HDisplay */ + 664, /* HSyncStart */ + 760, /* HSyncEnd */ + 800, /* HTotal */ + 0, /* HSkew */ + 400, /* VDisplay */ + 459, /* VSyncStart */ + 461, /* VSyncEnd */ + 525, /* VTotal */ + 0, /* VScan */ + V_NHSYNC | V_NVSYNC, /* Flags */ + -1, /* ClockIndex */ + 27000, /* SynthClock */ + 640, /* CRTC HDisplay */ + 648, /* CRTC HBlankStart */ + 664, /* CRTC HSyncStart */ + 760, /* CRTC HSyncEnd */ + 792, /* CRTC HBlankEnd */ + 800, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 400, /* CRTC VDisplay */ + 407, /* CRTC VBlankStart */ + 459, /* CRTC VSyncStart */ + 461, /* CRTC VSyncEnd */ + 490, /* CRTC VBlankEnd */ + 525, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +/* Built-in hi-res modes for the 6326. + * For some reason, our default mode lines and the + * clock calculation functions in sis_dac.c do no + * good job on higher clocks. It seems, the hardware + * needs some tricks so make mode with higher clock + * rates than ca. 120MHz work. I didn't bother trying + * to find out what exactly is going wrong, so I + * implemented two special modes instead for 1280x1024 + * and 1600x1200. These two are automatically added + * to the list if they are supported with the current + * depth. + * The data in the strucures below is a proximation, + * in sis_vga.c the register contents are fetched from + * fixed tables anyway. + */ +static DisplayModeRec SiS6326SIS1280x1024_75Mode = { + NULL, /* prev */ + NULL, /* next */ + "SIS1280x1024-75", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 135000, /* Clock frequency */ + 1280, /* HDisplay */ + 1296, /* HSyncStart */ + 1440, /* HSyncEnd */ + 1688, /* HTotal */ + 0, /* HSkew */ + 1024, /* VDisplay */ + 1025, /* VSyncStart */ + 1028, /* VSyncEnd */ + 1066, /* VTotal */ + 0, /* VScan */ + V_PHSYNC | V_PVSYNC, /* Flags */ + -1, /* ClockIndex */ + 135000, /* SynthClock */ + 1280, /* CRTC HDisplay */ + 1280, /* CRTC HBlankStart */ + 1296, /* CRTC HSyncStart */ + 1440, /* CRTC HSyncEnd */ + 1680, /* CRTC HBlankEnd */ + 1688, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 1024, /* CRTC VDisplay */ + 1024, /* CRTC VBlankStart */ + 1025, /* CRTC VSyncStart */ + 1028, /* CRTC VSyncEnd */ + 1065, /* CRTC VBlankEnd */ + 1066, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +static DisplayModeRec SiS6326SIS1600x1200_60Mode = { + NULL, /* prev */ + NULL, /* next */ + "SIS1600x1200-60", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 162000, /* Clock frequency */ + 1600, /* HDisplay */ + 1664, /* HSyncStart */ + 1856, /* HSyncEnd */ + 2160, /* HTotal */ + 0, /* HSkew */ + 1200, /* VDisplay */ + 1201, /* VSyncStart */ + 1204, /* VSyncEnd */ + 1250, /* VTotal */ + 0, /* VScan */ + V_PHSYNC | V_PVSYNC, /* Flags */ + -1, /* ClockIndex */ + 162000, /* SynthClock */ + 1600, /* CRTC HDisplay */ + 1600, /* CRTC HBlankStart */ + 1664, /* CRTC HSyncStart */ + 1856, /* CRTC HSyncEnd */ + 2152, /* CRTC HBlankEnd */ + 2160, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 1200, /* CRTC VDisplay */ + 1200, /* CRTC VBlankStart */ + 1201, /* CRTC VSyncStart */ + 1204, /* CRTC VSyncEnd */ + 1249, /* CRTC VBlankEnd */ + 1250, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +static const struct _SiSTVFilter301 { + unsigned char filter[7][4]; +} SiSTVFilter301[] = { + {{ {0x00,0xE0,0x10,0x60}, /* NTSCFilter - 320 */ + {0x00,0xEE,0x10,0x44}, + {0x00,0xF4,0x10,0x38}, + {0xF8,0xF4,0x18,0x38}, + {0xFC,0xFB,0x14,0x2A}, + {0x00,0x00,0x10,0x20}, + {0x00,0x04,0x10,0x18} }}, + {{ {0xF5,0xEE,0x1B,0x44}, /* NTSCFilter - 640 */ + {0xF8,0xF4,0x18,0x38}, + {0xEB,0x04,0x25,0x18}, + {0xF1,0x05,0x1F,0x16}, + {0xF6,0x06,0x1A,0x14}, + {0xFA,0x06,0x16,0x14}, + {0x00,0x04,0x10,0x18} }}, + {{ {0xEB,0x04,0x25,0x18}, /* NTSCFilter - 720 */ + {0xE7,0x0E,0x29,0x04}, + {0xEE,0x0C,0x22,0x08}, + {0xF6,0x0B,0x1A,0x0A}, + {0xF9,0x0A,0x17,0x0C}, + {0xFC,0x0A,0x14,0x0C}, + {0x00,0x08,0x10,0x10} }}, + {{ {0xEC,0x02,0x24,0x1C}, /* NTSCFilter - 800/400 */ + {0xF2,0x04,0x1E,0x18}, + {0xEB,0x15,0x25,0xF6}, + {0xF4,0x10,0x1C,0x00}, + {0xF8,0x0F,0x18,0x02}, + {0x00,0x04,0x10,0x18}, + {0x01,0x06,0x0F,0x14} }}, + {{ {0x00,0xE0,0x10,0x60}, /* PALFilter - 320 */ + {0x00,0xEE,0x10,0x44}, + {0x00,0xF4,0x10,0x38}, + {0xF8,0xF4,0x18,0x38}, + {0xFC,0xFB,0x14,0x2A}, + {0x00,0x00,0x10,0x20}, + {0x00,0x04,0x10,0x18} }}, + {{ {0xF5,0xEE,0x1B,0x44}, /* PALFilter - 640 */ + {0xF8,0xF4,0x18,0x38}, + {0xF1,0xF7,0x1F,0x32}, + {0xF5,0xFB,0x1B,0x2A}, + {0xF9,0xFF,0x17,0x22}, + {0xFB,0x01,0x15,0x1E}, + {0x00,0x04,0x10,0x18} }}, + {{ {0xF5,0xEE,0x1B,0x2A}, /* PALFilter - 720 */ + {0xEE,0xFE,0x22,0x24}, + {0xF3,0x00,0x1D,0x20}, + {0xF9,0x03,0x17,0x1A}, + {0xFB,0x02,0x14,0x1E}, + {0xFB,0x04,0x15,0x18}, + {0x00,0x06,0x10,0x14} }}, + {{ {0xF5,0xEE,0x1B,0x44}, /* PALFilter - 800/400 */ + {0xF8,0xF4,0x18,0x38}, + {0xFC,0xFB,0x14,0x2A}, + {0xEB,0x05,0x25,0x16}, + {0xF1,0x05,0x1F,0x16}, + {0xFA,0x07,0x16,0x12}, + {0x00,0x07,0x10,0x12} }} +}; + +static const struct _SiSTVFilter301B { + unsigned char filter[7][7]; +} SiSTVFilter301B[] = { + {{ {0x01,0x02,0xfb,0xf8,0x06,0x27,0x3a}, /* NTSC - 640 */ + {0x01,0x02,0xfe,0xf7,0x03,0x27,0x3c}, + {0x01,0x01,0x00,0xf6,0x00,0x28,0x40}, + {0xff,0x03,0x02,0xf6,0xfc,0x27,0x46}, + {0xff,0x01,0x04,0xf8,0xfa,0x27,0x46}, + {0xff,0x01,0x05,0xf9,0xf7,0x26,0x4a}, + {0xff,0xff,0x05,0xfc,0xf4,0x24,0x52} }}, + {{ {0x01,0x00,0xfb,0xfb,0x0b,0x25,0x32}, /* NTSC - 720 (?) */ + {0x01,0x01,0xfb,0xf9,0x09,0x26,0x36}, + {0x01,0x02,0xfc,0xf8,0x06,0x27,0x38}, + {0x01,0x02,0xfe,0xf7,0x03,0x27,0x3c}, + {0x01,0x03,0xff,0xf6,0x00,0x27,0x40}, + {0xff,0x03,0x02,0xf6,0xfe,0x27,0x42}, + {0xff,0x02,0x03,0xf7,0xfb,0x27,0x46} }}, + {{ {0x01,0xfe,0xfb,0xfe,0x0e,0x23,0x2e}, /* NTSC - 800 */ + {0x01,0xff,0xfb,0xfc,0x0c,0x25,0x30}, + {0x01,0x00,0xfb,0xfa,0x0a,0x26,0x34}, + {0x01,0x01,0xfc,0xf8,0x08,0x26,0x38}, + {0x01,0x02,0xfd,0xf7,0x06,0x27,0x38}, + {0x01,0x02,0xfe,0xf7,0x03,0x27,0x3c}, + {0xff,0x03,0x00,0xf6,0x00,0x27,0x42} }}, + {{ {0xff,0xfd,0xfe,0x05,0x11,0x1e,0x24}, /* NTSC - 1024 */ + {0xff,0xfd,0xfd,0x04,0x11,0x1f,0x26}, + {0xff,0xfd,0xfc,0x02,0x10,0x22,0x28}, + {0xff,0xff,0xfc,0x00,0x0f,0x22,0x28}, + {0x01,0xfe,0xfb,0xff,0x0e,0x23,0x2c}, + {0x01,0xff,0xfb,0xfd,0x0d,0x24,0x2e}, + {0x01,0xff,0xfb,0xfb,0x0c,0x25,0x32} }}, + {{ {0x01,0x02,0xfb,0xf8,0x06,0x27,0x3a}, /* PAL - 640 */ + {0x01,0x02,0xfe,0xf7,0x03,0x27,0x3c}, + {0x01,0x01,0x00,0xf6,0x00,0x28,0x40}, + {0xff,0x03,0x02,0xf6,0xfc,0x27,0x46}, + {0xff,0x01,0x04,0xf8,0xfa,0x27,0x46}, + {0xff,0x01,0x05,0xf9,0xf7,0x26,0x4a}, + {0xff,0xff,0x05,0xfc,0xf4,0x24,0x52} }}, + {{ {0x01,0x00,0xfb,0xfb,0x0b,0x25,0x32}, /* PAL - 720/768 */ + {0x01,0x01,0xfb,0xf9,0x09,0x26,0x36}, + {0x01,0x02,0xfc,0xf8,0x06,0x27,0x38}, + {0x01,0x02,0xfe,0xf7,0x03,0x27,0x3c}, + {0x01,0x03,0xff,0xf6,0x00,0x27,0x40}, + {0xff,0x03,0x02,0xf6,0xfe,0x27,0x42}, + {0xff,0x02,0x03,0xf7,0xfb,0x27,0x46} }}, + {{ {0x01,0xfe,0xfb,0xfe,0x0e,0x23,0x2e}, /* PAL - 800 */ + {0x01,0xff,0xfb,0xfc,0x0c,0x25,0x30}, + {0x01,0x00,0xfb,0xfa,0x0a,0x26,0x34}, + {0x01,0x01,0xfc,0xf8,0x08,0x26,0x38}, + {0x01,0x02,0xfd,0xf7,0x06,0x27,0x38}, + {0x01,0x02,0xfe,0xf7,0x03,0x27,0x3c}, + {0xff,0x03,0x00,0xf6,0x00,0x27,0x42} }}, + {{ {0xff,0xfd,0xfe,0x05,0x11,0x1e,0x24}, /* PAL - 1024 */ + {0xff,0xfd,0xfd,0x04,0x11,0x1f,0x26}, + {0xff,0xfd,0xfc,0x02,0x10,0x22,0x28}, + {0xff,0xff,0xfc,0x00,0x0f,0x22,0x28}, + {0x01,0xfe,0xfb,0xff,0x0e,0x23,0x2c}, + {0x01,0xff,0xfb,0xfd,0x0d,0x24,0x2e}, + {0x01,0xff,0xfb,0xfb,0x0c,0x25,0x32} }} +}; + +typedef struct _SiSTVVScale { + unsigned short ScaleVDE; + int sindex; + unsigned short RealVDE; +#if 0 + unsigned short HT, HRS, HRE, VT, VRS, VRE; + unsigned short NFF, HCFACT, HCMAX, VBHT, VBVT, VBHRS; + unsigned short HT300, HRS300, HRE300, VT300, VRS300, VRE300; + unsigned short NFF300, HCFACT300, HCMAX300, VBHT300, VBVT300, VBHRS300; +#endif + unsigned short reg[24]; +} MySiSTVVScale, *MySiSTVVScalePtr; + +static const MySiSTVVScale SiSTVVScale[] = { + { 0x01D6, 3, 480, /* NTSC 640 */ + { 0x037C, 0x02B0, 0x00EF, 0x01FA, 0x01E7, 0x01E9, + 0x0000, 0x004C, 0x008F, 0x037C, 0x01FB, 0x00D4, + 0x037C, 0x02CB, 0x0049, 0x01FB, 0x01EE, 0x01F0, + 0x0000, 0x004C, 0x008F, 0x037C, 0x01FB, 0x00E0 } + }, + { 0x01CC, 2, 480, + { 0x0369, 0x02AD, 0x00E7, 0x01FF, 0x01E8, 0x01EB, + 0x0000, 0x004C, 0x008F, 0x0369, 0x0200, 0x00D4, + 0x0369, 0x02C6, 0x003A, 0x0200, 0x01F0, 0x01F3, + 0x0000, 0x004C, 0x008F, 0x0369, 0x0200, 0x00E0 } + }, + { 0x01C2, 1, 480, + { 0x0356, 0x02AB, 0x00E0, 0x0204, 0x01E9, 0x01EC, + 0x0000, 0x004C, 0x008F, 0x0356, 0x0205, 0x00D4, + 0x0356, 0x02C1, 0x002B, 0x0205, 0x01F3, 0x01F6, + 0x0000, 0x004C, 0x008F, 0x0356, 0x0205, 0x00E0 } + }, + { 0x01B8, 0, 480, /* default */ + { 0x0343, 0x02A9, 0x00DA, 0x0209, 0x01EA, 0x01ED, + 0x0000, 0x004C, 0x008F, 0x0343, 0x020A, 0x00D4, + 0x0343, 0x02BD, 0x001F, 0x020A, 0x01F5, 0x01F8, + 0x0000, 0x004C, 0x008F, 0x0343, 0x020A, 0x00E0 } + }, + { 0x01AE, -1, 480, + { 0x035B, 0x02AC, 0x00E3, 0x020E, 0x01EC, 0x01F0, + 0x0000, 0x0050, 0x008F, 0x035B, 0x020F, 0x0152, + 0x035B, 0x02C3, 0x0031, 0x020F, 0x01F8, 0x01FC, + 0x0000, 0x0050, 0x008F, 0x035B, 0x020F, 0x015E } + }, + { 0x01A4, -2, 480, + { 0x0347, 0x02A9, 0x00DB, 0x0213, 0x01ED, 0x01F1, + 0x0000, 0x0050, 0x008F, 0x0347, 0x0214, 0x0102, + 0x0347, 0x02BE, 0x0022, 0x0214, 0x01FA, 0x01FE, + 0x0000, 0x0050, 0x008F, 0x0347, 0x0214, 0x010E } + }, + { 0x019A, -3, 480, + { 0x0333, 0x02A7, 0x00D4, 0x0218, 0x01EE, 0x01F2, + 0x0000, 0x0050, 0x008F, 0x0333, 0x0219, 0x016A, + 0x0333, 0x02B9, 0x0013, 0x0219, 0x01FD, 0x0201, + 0x0000, 0x0050, 0x008F, 0x0333, 0x0219, 0x016A } + }, + { 0x01D6, 3, 480, /* NTSC 720 */ + { 0x037C, 0x0307, 0x005D, 0x01FB, 0x01EE, 0x01F0, + 0x0000, 0x004C, 0x008F, 0x037C, 0x01FB, 0x0090 } + }, + { 0x01CC, 2, 480, + { 0x0369, 0x0302, 0x004E, 0x0200, 0x01F0, 0x01F3, + 0x0000, 0x004C, 0x008F, 0x0369, 0x0200, 0x0090 } + }, + { 0x01C2, 1, 480, + { 0x0356, 0x02FD, 0x003F, 0x0205, 0x01F3, 0x01F6, + 0x0000, 0x004C, 0x008F, 0x0356, 0x0205, 0x0090 } + }, + { 0x01B8, 0, 480, /* default */ + { 0x0343, 0x02F9, 0x0033, 0x020A, 0x01F5, 0x01F8, + 0x0000, 0x004C, 0x008F, 0x0343, 0x020A, 0x0090 } + }, + { 0x01AE, -1, 480, + { 0x035B, 0x02FF, 0x0045, 0x020F, 0x01F8, 0x01FC, + 0x0000, 0x0050, 0x008F, 0x035B, 0x020F, 0x010E } + }, + { 0x01A4, -2, 480, + { 0x0347, 0x02FA, 0x0036, 0x0214, 0x01FA, 0x01FE, + 0x0000, 0x0050, 0x008F, 0x0347, 0x0214, 0x00BE } + }, + { 0x019A, -3, 480, + { 0x0333, 0x02F5, 0x0027, 0x0219, 0x01FD, 0x0201, + 0x0000, 0x0050, 0x008F, 0x0333, 0x0219, 0x0136 } + }, + { 0x01D6, 3, 600, /* NTSC 800 */ + { 0x0438, 0x0353, 0x0099, 0x0272, 0x025F, 0x0261, + 0x0000, 0x0073, 0x008F, 0x0438, 0x0273, 0x020A, + 0x0438, 0x0372, 0x00FE, 0x0273, 0x0266, 0x0268, + 0x0000, 0x0073, 0x008F, 0x0438, 0x0273, 0x020A } + }, + { 0x01CC, 2, 600, + { 0x0421, 0x0350, 0x0090, 0x0277, 0x0260, 0x0263, + 0x0000, 0x0073, 0x008F, 0x0421, 0x0278, 0x020A, + 0x0421, 0x036C, 0x00EC, 0x0278, 0x0268, 0x026B, + 0x0000, 0x0073, 0x008F, 0x0421, 0x0278, 0x020A } + }, + { 0x01C2, 1, 600, + { 0x0413, 0x034F, 0x008C, 0x027C, 0x0261, 0x0264, + 0x0000, 0x0074, 0x008F, 0x0413, 0x027D, 0x01FE, + 0x0413, 0x0369, 0x00E3, 0x027D, 0x026B, 0x026E, + 0x0000, 0x0074, 0x008F, 0x0413, 0x027D, 0x020C } + }, + { 0x01B8, 0, 600, /* default */ + { 0x041F, 0x0350, 0x0090, 0x0281, 0x0262, 0x0265, + 0x0000, 0x0078, 0x008F, 0x041F, 0x0282, 0x0220, + 0x041F, 0x036C, 0x00EC, 0x0282, 0x026D, 0x0270, + 0x0001, 0x0078, 0x008F, 0x041F, 0x0282, 0x0220 } + }, + { 0x01AE, -1, 600, + { 0x0407, 0x034D, 0x0087, 0x0286, 0x0264, 0x0268, + 0x0000, 0x0078, 0x008F, 0x0407, 0x0287, 0x0220, + 0x0407, 0x0366, 0x00DA, 0x0287, 0x0270, 0x0274, + 0x0001, 0x0078, 0x008F, 0x0407, 0x0287, 0x0220 } + }, + { 0x01A4, -2, 600, + { 0x03EF, 0x034A, 0x007E, 0x028B, 0x0265, 0x0269, + 0x0000, 0x0078, 0x008F, 0x03EF, 0x028C, 0x0220, + 0x03EF, 0x0360, 0x00C8, 0x028C, 0x0272, 0x0276, + 0x0001, 0x0078, 0x008F, 0x03EF, 0x028C, 0x0220 } + }, + { 0x019A, -3, 600, + { 0x0429, 0x0351, 0x0093, 0x0290, 0x0266, 0x026A, + 0x0000, 0x0082, 0x008F, 0x0429, 0x0291, 0x024E, + 0x0429, 0x036E, 0x00F2, 0x0291, 0x0275, 0x0279, + 0x0001, 0x0082, 0x008F, 0x0429, 0x0291, 0x024E } + }, +#if 0 + { 0x01B8, 0, 768, /* NTSC 1024 - v-scaling not supported */ + { 0x044B, 0x041A, 0x002D, 0x0329, 0x030A, 0x030D, + 0x0000, 0x0001, 0x0001, 0x044B, 0x032A, 0x02D2 } + }, +#endif + + { 0x0230, 3, 480, /* PAL 640 */ + { 0x0371, 0x02AE, 0x00EA, 0x01FF, 0x01E8, 0x01EB, + 0x0000, 0x0007, 0x0010, 0x0371, 0x0200, 0x0032, + 0x0371, 0x02C8, 0x0040, 0x0200, 0x01F0, 0x01F3, + 0x0000, 0x000E, 0x0020, 0x0371, 0x0200, 0x0032 } + }, + { 0x0226, 2, 480, + { 0x0383, 0x02B1, 0x00F2, 0x0204, 0x01E9, 0x01EC, + 0x0000, 0x0005, 0x000B, 0x0383, 0x0205, 0x0032, + 0x0383, 0x02CD, 0x004F, 0x0205, 0x01F3, 0x01F6, + 0x0000, 0x0005, 0x000B, 0x0383, 0x0205, 0x0032 } + }, + { 0x021C, 1, 480, + { 0x035F, 0x02AC, 0x00E4, 0x0209, 0x01EA, 0x01ED, + 0x0000, 0x0004, 0x0009, 0x035F, 0x020A, 0x0032, + 0x035F, 0x02C4, 0x0034, 0x020A, 0x01F5, 0x01F8, + 0x0000, 0x0004, 0x0009, 0x035F, 0x020A, 0x0032 } + }, + { 0x0212, 0, 480, /* default */ + { 0x034F, 0x02AA, 0x00DE, 0x020E, 0x01EC, 0x01F0, + 0x0000, 0x0004, 0x0009, 0x034F, 0x020F, 0x0032, + 0x034F, 0x02C0, 0x0028, 0x020F, 0x01F8, 0x01FC, + 0x0000, 0x0004, 0x0009, 0x034F, 0x020F, 0x0032 } + }, + { 0x0208, -1, 480, + { 0x033F, 0x02A8, 0x00D8, 0x0213, 0x01ED, 0x01F1, + 0x0000, 0x0004, 0x0009, 0x033F, 0x0214, 0x0032, + 0x033F, 0x02BC, 0x001C, 0x0214, 0x01FA, 0x01FE, + 0x0000, 0x0004, 0x0009, 0x033F, 0x0214, 0x0032 } + }, + { 0x01FE, -2, 480, + { 0x0395, 0x02B3, 0x00F8, 0x0218, 0x01EE, 0x01F2, + 0x0000, 0x0001, 0x0002, 0x0395, 0x0219, 0x0032, + 0x0395, 0x02D1, 0x005B, 0x0219, 0x01FD, 0x0201, + 0x0000, 0x0001, 0x0002, 0x0395, 0x0219, 0x0032 } + }, + { 0x01F4, -3, 480, + { 0x0383, 0x02B1, 0x00F2, 0x021D, 0x01EF, 0x01F3, + 0x0000, 0x0001, 0x0002, 0x0383, 0x021E, 0x0032, + 0x0383, 0x02CD, 0x004F, 0x021E, 0x01FF, 0x0203, + 0x0000, 0x0001, 0x0002, 0x0383, 0x021E, 0x0032 } + }, + { 0x0230, 2, 576, /* PAL 720 */ + { 0x03BF, 0x0318, 0x0090, 0x0260, 0x0250, 0x0253, + 0x0000, 0x0004, 0x0007, 0x03BF, 0x0260, 0x00E0, + 0x6954, 0x6C6C, 0x5320, 0x666F, 0x6169, 0x4220, + 0x7265, 0x746E, 0x7373, 0x6E6F, 0x0260, 0x00E0 } + }, + { 0x0226, 1, 576, + { 0x03DD, 0x031F, 0x00A5, 0x0265, 0x0253, 0x0256, + 0x0000, 0x0003, 0x0005, 0x03DD, 0x0265, 0x013B, + 0x7242, 0x756F, 0x6867, 0x2074, 0x6F74, 0x7920, + 0x756F, 0x6220, 0x2079, 0x6F6E, 0x2074, 0x2061 } + }, + { 0x021C, 0, 576, /* default */ + { 0x0437, 0x0336, 0x00EA, 0x026A, 0x0255, 0x0258, + 0x0000, 0x0002, 0x0003, 0x0437, 0x026A, 0x0180, + 0x656D, 0x6572, 0x5720, 0x7A69, 0x7261, 0x2064, + 0x7562, 0x2074, 0x6874, 0x2065, 0x0274, 0x01CE } + }, + { 0x0212, -1, 576, + { 0x0423, 0x0331, 0x00DB, 0x026F, 0x0258, 0x025C, + 0x0001, 0x0002, 0x0003, 0x0423, 0x026F, 0x01CA, + 0x6957, 0x617A, 0x6472, 0x4520, 0x7478, 0x6172, + 0x726F, 0x6964, 0x616E, 0x7269, 0x3A65, 0x01CE } + }, + { 0x0208, -2, 576, + { 0x040F, 0x032C, 0x00CC, 0x0274, 0x025A, 0x025E, + 0x0000, 0x0002, 0x0003, 0x040F, 0x0274, 0x01CA, + 0x6854, 0x6D6F, 0x7361, 0x5720, 0x6E69, 0x7369, + 0x6863, 0x6F68, 0x6566, 0x2172, 0x027E, 0x01CA } + }, + { 0x01FE, -3, 576, + { 0x03FB, 0x0327, 0x00BD, 0x0279, 0x025D, 0x0261, + 0x0000, 0x0002, 0x0003, 0x03FB, 0x0279, 0x01CA, + } + }, + { 0x01F4, -4, 576, + { 0x03E7, 0x0322, 0x00AE, 0x027E, 0x025F, 0x0263, + 0x0000, 0x0002, 0x0003, 0x03E7, 0x027E, 0x01CA, + 0x6854, 0x7369, 0x7320, 0x6170, 0x6563, 0x6620, + 0x726F, 0x7320, 0x6C61, 0x0365, 0x027F, 0x01FE } + }, + { 0x0230, 3, 600, /* PAL 800 */ + { 0x047F, 0x035C, 0x00B4, 0x0277, 0x0260, 0x0263, + 0x0000, 0x0005, 0x0007, 0x047F, 0x0278, 0x0170, + 0x047F, 0x0384, 0x0034, 0x0278, 0x0268, 0x026B, + 0x0000, 0x0005, 0x0007, 0x047F, 0x0278, 0x017E } + }, + { 0x0226, 2, 600, + { 0x044B, 0x0356, 0x00A1, 0x027C, 0x0261, 0x0264, + 0x0000, 0x0019, 0x0024, 0x044B, 0x027D, 0x0150, + 0x044B, 0x0377, 0x000D, 0x027D, 0x026B, 0x026E, + 0x0000, 0x0019, 0x0024, 0x044B, 0x027D, 0x015E } + }, + { 0x021C, 1, 600, + { 0x0437, 0x0353, 0x0099, 0x0281, 0x0262, 0x0265, + 0x0000, 0x0019, 0x0024, 0x0437, 0x0282, 0x0150, + 0x0437, 0x0372, 0x00FE, 0x0282, 0x026D, 0x0270, + 0x0000, 0x0019, 0x0024, 0x0437, 0x0282, 0x015E } + }, + { 0x0212, 0, 600, /* default */ + { 0x0423, 0x0351, 0x0092, 0x0286, 0x0264, 0x0268, + 0x0000, 0x0019, 0x0024, 0x0423, 0x0287, 0x01C8, + 0x0423, 0x036D, 0x00EF, 0x0287, 0x0270, 0x0274, + 0x0000, 0x0019, 0x0024, 0x0423, 0x0287, 0x01D6 } + }, + { 0x0208, -1, 600, + { 0x040F, 0x034E, 0x008A, 0x028B, 0x0265, 0x0269, + 0x0000, 0x0019, 0x0024, 0x040F, 0x028C, 0x01A0, + 0x040F, 0x0368, 0x00E0, 0x028C, 0x0272, 0x0276, + 0x0000, 0x0019, 0x0024, 0x040F, 0x028C, 0x01AE } + }, + { 0x01FE, -2, 600, + { 0x03FB, 0x034C, 0x0083, 0x0290, 0x0266, 0x026A, + 0x0000, 0x0019, 0x0024, 0x03FB, 0x0291, 0x01C8, + 0x03FB, 0x0363, 0x00D1, 0x0291, 0x0275, 0x0279, + 0x0000, 0x0019, 0x0024, 0x03FB, 0x0291, 0x01D6 } + }, + { 0x01F4, -3, 600, + { 0x0437, 0x0353, 0x0099, 0x0295, 0x0267, 0x026B, + 0x0000, 0x0003, 0x0004, 0x0437, 0x0296, 0x01BF, + 0x0437, 0x0372, 0x00FE, 0x0296, 0x0277, 0x027B, + 0x0000, 0x0003, 0x0004, 0x0437, 0x0296, 0x01BA } + }, +#if 0 + { 0x0208, 0, 768, /* PAL 1024 - v-scaling not supported */ + { 0x0491, 0x0422, 0x0046, 0x0333, 0x030D, 0x0311, + 0x0000, 0x0001, 0x0001, 0x0491, 0x0334, 0x02AE } + } +#endif +}; + +unsigned const char SiSScalingP1Regs[] = { + 0x08,0x09,0x0b,0x0c,0x0d,0x0e,0x10,0x11,0x12 +}; +unsigned const char SiSScalingP4Regs[] = { + 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b +}; + + +USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN hcm); +USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN hcm); +unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value); + +void SISMergePointerMoved(int scrnIndex, int x, int y); + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_opt.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_opt.c index a44b39477..60883930f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_opt.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_opt.c @@ -1,94 +1,1507 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_opt.c,v 1.2 2000/02/12 23:08:06 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_opt.c,v 1.25 2003/08/10 21:25:38 twini Exp $ */ +/* + * SiS driver option evaluation + * + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * Based on code by ? (included in XFree86 4.1) + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the supplier not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The supplier makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE SUPPLIER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Thomas Winischhofer <thomas@winischhofer.net> + * ? + */ #include "xf86.h" +#include "xf86PciInfo.h" +#include "xf86str.h" +#include "xf86Cursor.h" #include "sis.h" +extern const customttable mycustomttable[]; + typedef enum { OPTION_SW_CURSOR, OPTION_HW_CURSOR, - OPTION_PCI_RETRY, - OPTION_RGB_BITS, +/* OPTION_PCI_RETRY, */ OPTION_NOACCEL, OPTION_TURBOQUEUE, OPTION_FAST_VRAM, - OPTION_SET_MEMCLOCK + OPTION_NOHOSTBUS, +/* OPTION_SET_MEMCLOCK, */ + OPTION_FORCE_CRT2TYPE, + OPTION_SHADOW_FB, + OPTION_ROTATE, + OPTION_NOXVIDEO, + OPTION_VESA, + OPTION_MAXXFBMEM, + OPTION_FORCECRT1, + OPTION_XVONCRT2, + OPTION_PDC, + OPTION_TVSTANDARD, + OPTION_USEROMDATA, + OPTION_NOINTERNALMODES, + OPTION_USEOEM, + OPTION_NOYV12, + OPTION_CHTVOVERSCAN, + OPTION_CHTVSOVERSCAN, + OPTION_CHTVLUMABANDWIDTHCVBS, + OPTION_CHTVLUMABANDWIDTHSVIDEO, + OPTION_CHTVLUMAFLICKERFILTER, + OPTION_CHTVCHROMABANDWIDTH, + OPTION_CHTVCHROMAFLICKERFILTER, + OPTION_CHTVCVBSCOLOR, + OPTION_CHTVTEXTENHANCE, + OPTION_CHTVCONTRAST, + OPTION_SISTVEDGEENHANCE, + OPTION_SISTVANTIFLICKER, + OPTION_SISTVSATURATION, + OPTION_SISTVCHROMAFILTER, + OPTION_SISTVLUMAFILTER, + OPTION_SISTVCOLCALIBFINE, + OPTION_SISTVCOLCALIBCOARSE, + OPTION_TVXPOSOFFSET, + OPTION_TVYPOSOFFSET, + OPTION_TVXSCALE, + OPTION_TVYSCALE, + OPTION_SIS6326ANTIFLICKER, + OPTION_SIS6326ENABLEYFILTER, + OPTION_SIS6326YFILTERSTRONG, + OPTION_SIS6326FORCETVPPLUG, + OPTION_SIS6326FSCADJUST, + OPTION_CHTVTYPE, + OPTION_USERGBCURSOR, + OPTION_USERGBCURSORBLEND, + OPTION_USERGBCURSORBLENDTH, + OPTION_RESTOREBYSET, + OPTION_NODDCFORCRT2, + OPTION_FORCECRT2REDETECTION, + OPTION_CRT1GAMMA, + OPTION_CRT2GAMMA, + OPTION_XVDEFCONTRAST, + OPTION_XVDEFBRIGHTNESS, + OPTION_XVDEFHUE, + OPTION_XVDEFSATURATION, + OPTION_XVDEFDISABLEGFX, + OPTION_XVDEFDISABLEGFXLR, + OPTION_XVMEMCPY, + OPTION_XVUSECHROMAKEY, + OPTION_XVCHROMAMIN, + OPTION_XVCHROMAMAX, + OPTION_XVDISABLECOLORKEY, + OPTION_XVINSIDECHROMAKEY, + OPTION_XVYUVCHROMAKEY, + OPTION_SCALELCD, + OPTION_SPECIALTIMING, + OPTION_ENABLEHOTKEY, + OPTION_MERGEDFB, + OPTION_CRT2HSYNC, + OPTION_CRT2VREFRESH, + OPTION_CRT2POS, + OPTION_METAMODES, + OPTION_MERGEDFB2, + OPTION_CRT2HSYNC2, + OPTION_CRT2VREFRESH2, + OPTION_CRT2POS2, + OPTION_NOSISXINERAMA, + OPTION_NOSISXINERAMA2, + OPTION_CRT2ISSCRN0, + OPTION_ENABLESISCTRL, + OPTION_STOREDBRIR, + OPTION_STOREDBRIG, + OPTION_STOREDBRIB, + OPTION_STOREDPBRIR, + OPTION_STOREDPBRIG, + OPTION_STOREDPBRIB, +#ifdef SIS_CP + SIS_CP_OPT_OPTIONS +#endif + OPTION_PSEUDO } SISOpts; -static OptionInfoRec SISOptions[] = { - { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_RGB_BITS, "rgbbits", OPTV_INTEGER, {0}, -1 }, - { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_TURBOQUEUE, "TurboQueue", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_SET_MEMCLOCK, "SetMClk", OPTV_FREQ, {0}, -1 }, - { OPTION_FAST_VRAM, "FastVram", OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, OPTV_NONE, {0}, FALSE } +static const OptionInfoRec SISOptions[] = { + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, +/* { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, */ + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_TURBOQUEUE, "TurboQueue", OPTV_BOOLEAN, {0}, FALSE }, +/* { OPTION_SET_MEMCLOCK, "SetMClk", OPTV_FREQ, {0}, -1 }, */ + { OPTION_FAST_VRAM, "FastVram", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOHOSTBUS, "NoHostBus", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FORCE_CRT2TYPE, "ForceCRT2Type", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_NOXVIDEO, "NoXvideo", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VESA, "Vesa", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_MAXXFBMEM, "MaxXFBMem", OPTV_INTEGER, {0}, -1 }, + { OPTION_FORCECRT1, "ForceCRT1", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_XVONCRT2, "XvOnCRT2", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_PDC, "PanelDelayCompensation", OPTV_INTEGER, {0}, -1 }, + { OPTION_TVSTANDARD, "TVStandard", OPTV_STRING, {0}, -1 }, + { OPTION_USEROMDATA, "UseROMData", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_NOINTERNALMODES, "NoInternalModes", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_USEOEM, "UseOEMData", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_NOYV12, "NoYV12", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_CHTVTYPE, "CHTVType", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_CHTVOVERSCAN, "CHTVOverscan", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_CHTVSOVERSCAN, "CHTVSuperOverscan", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_CHTVLUMABANDWIDTHCVBS, "CHTVLumaBandwidthCVBS", OPTV_INTEGER, {0}, -1 }, + { OPTION_CHTVLUMABANDWIDTHSVIDEO, "CHTVLumaBandwidthSVIDEO",OPTV_INTEGER, {0}, -1 }, + { OPTION_CHTVLUMAFLICKERFILTER, "CHTVLumaFlickerFilter", OPTV_INTEGER, {0}, -1 }, + { OPTION_CHTVCHROMABANDWIDTH, "CHTVChromaBandwidth", OPTV_INTEGER, {0}, -1 }, + { OPTION_CHTVCHROMAFLICKERFILTER, "CHTVChromaFlickerFilter",OPTV_INTEGER, {0}, -1 }, + { OPTION_CHTVCVBSCOLOR, "CHTVCVBSColor", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_CHTVTEXTENHANCE, "CHTVTextEnhance", OPTV_INTEGER, {0}, -1 }, + { OPTION_CHTVCONTRAST, "CHTVContrast", OPTV_INTEGER, {0}, -1 }, + { OPTION_SISTVEDGEENHANCE, "SISTVEdgeEnhance", OPTV_INTEGER, {0}, -1 }, + { OPTION_SISTVANTIFLICKER, "SISTVAntiFlicker", OPTV_STRING, {0}, FALSE }, + { OPTION_SISTVSATURATION, "SISTVSaturation", OPTV_INTEGER, {0}, -1 }, + { OPTION_SISTVCHROMAFILTER, "SISTVCFilter", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_SISTVLUMAFILTER, "SISTVYFilter", OPTV_INTEGER, {0}, -1 }, + { OPTION_SISTVCOLCALIBFINE, "SISTVColorCalibFine", OPTV_INTEGER, {0}, -1 }, + { OPTION_SISTVCOLCALIBCOARSE, "SISTVColorCalibCoarse", OPTV_INTEGER, {0}, -1 }, + { OPTION_TVXSCALE, "SISTVXScale", OPTV_INTEGER, {0}, -1 }, + { OPTION_TVYSCALE, "SISTVYScale", OPTV_INTEGER, {0}, -1 }, + { OPTION_TVXPOSOFFSET, "TVXPosOffset", OPTV_INTEGER, {0}, -1 }, + { OPTION_TVYPOSOFFSET, "TVYPosOffset", OPTV_INTEGER, {0}, -1 }, + { OPTION_SIS6326ANTIFLICKER, "SIS6326TVAntiFlicker", OPTV_STRING, {0}, FALSE }, + { OPTION_SIS6326ENABLEYFILTER, "SIS6326TVEnableYFilter", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_SIS6326YFILTERSTRONG, "SIS6326TVYFilterStrong", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_SIS6326FORCETVPPLUG, "SIS6326TVForcePlug", OPTV_STRING, {0}, -1 }, + { OPTION_SIS6326FSCADJUST, "SIS6326FSCAdjust", OPTV_INTEGER, {0}, -1 }, + { OPTION_USERGBCURSOR, "UseColorHWCursor", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_USERGBCURSORBLEND, "ColorHWCursorBlending", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_USERGBCURSORBLENDTH, "ColorHWCursorBlendThreshold", OPTV_INTEGER, {0}, -1 }, + { OPTION_RESTOREBYSET, "RestoreBySetMode", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_NODDCFORCRT2, "NoCRT2Detection", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_FORCECRT2REDETECTION, "ForceCRT2ReDetection", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_CRT1GAMMA, "CRT1Gamma", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_CRT2GAMMA, "CRT2Gamma", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_XVDEFCONTRAST, "XvDefaultContrast", OPTV_INTEGER, {0}, -1 }, + { OPTION_XVDEFBRIGHTNESS, "XvDefaultBrightness", OPTV_INTEGER, {0}, -1 }, + { OPTION_XVDEFHUE, "XvDefaultHue", OPTV_INTEGER, {0}, -1 }, + { OPTION_XVDEFSATURATION, "XvDefaultSaturation", OPTV_INTEGER, {0}, -1 }, + { OPTION_XVDEFDISABLEGFX, "XvDefaultDisableGfx", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_XVDEFDISABLEGFXLR, "XvDefaultDisableGfxLR", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_XVCHROMAMIN, "XvChromaMin", OPTV_INTEGER, {0}, -1 }, + { OPTION_XVCHROMAMAX, "XvChromaMax", OPTV_INTEGER, {0}, -1 }, + { OPTION_XVUSECHROMAKEY, "XvUseChromaKey", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_XVINSIDECHROMAKEY, "XvInsideChromaKey", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_XVYUVCHROMAKEY, "XvYUVChromaKey", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_XVDISABLECOLORKEY, "XvDisableColorKey", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_XVMEMCPY, "XvUseMemcpy", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_SCALELCD, "ScaleLCD", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_ENABLEHOTKEY, "EnableHotkey", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_SPECIALTIMING, "SpecialTiming", OPTV_STRING, {0}, -1 }, + { OPTION_ENABLESISCTRL, "EnableSiSCtrl", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_STOREDBRIR, "StoredGammaBrightnessRed", OPTV_INTEGER, {0}, -1 }, + { OPTION_STOREDBRIG, "StoredGammaBrightnessGreen", OPTV_INTEGER, {0}, -1 }, + { OPTION_STOREDBRIB, "StoredGammaBrightnessBlue", OPTV_INTEGER, {0}, -1 }, + { OPTION_STOREDPBRIR, "StoredGammaPreBrightnessRed", OPTV_INTEGER, {0}, -1 }, + { OPTION_STOREDPBRIG, "StoredGammaPreBrightnessGreen", OPTV_INTEGER, {0}, -1 }, + { OPTION_STOREDPBRIB, "StoredGammaPreBrightnessBlue", OPTV_INTEGER, {0}, -1 }, +#ifdef SISMERGED + { OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CRT2HSYNC, "CRT2HSync", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_CRT2VREFRESH, "CRT2VRefresh", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_CRT2POS, "CRT2Position", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_MERGEDFB2, "TwinView", OPTV_BOOLEAN, {0}, FALSE }, /* alias */ + { OPTION_CRT2HSYNC2, "SecondMonitorHorizSync", OPTV_ANYSTR, {0}, FALSE }, /* alias */ + { OPTION_CRT2VREFRESH2, "SecondMonitorVertRefresh", OPTV_ANYSTR, {0}, FALSE }, /* alias */ + { OPTION_CRT2POS2, "TwinViewOrientation", OPTV_ANYSTR, {0}, FALSE }, /* alias */ +#ifdef SISXINERAMA + { OPTION_NOSISXINERAMA, "NoMergedXinerama", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CRT2ISSCRN0, "MergedXineramaCRT2IsScreen0", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOSISXINERAMA2, "NoTwinviewXineramaInfo", OPTV_BOOLEAN, {0}, FALSE }, /* alias */ +#endif +#endif +#ifdef SIS_CP + SIS_CP_OPTION_DETAIL +#endif + { -1, NULL, OPTV_NONE, {0}, FALSE } }; void SiSOptions(ScrnInfoPtr pScrn) { - SISPtr pSiS = SISPTR(pScrn); - MessageType from; - double temp; + SISPtr pSiS = SISPTR(pScrn); + MessageType from; +/* double temp; */ + char *strptr; + static const char *mybadparm = "\"%s\" is is not a valid parameter for option \"%s\"\n"; + static const char *disabledstr = "disabled"; + static const char *enabledstr = "enabled"; + static const char *ilrangestr = "Illegal %s parameter. Valid range is %d through %d\n"; + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + + /* Process the options */ + if(!(pSiS->Options = xalloc(sizeof(SISOptions)))) + return; + + memcpy(pSiS->Options, SISOptions, sizeof(SISOptions)); + + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSiS->Options); + + /* Set defaults */ + + pSiS->newFastVram = -1; + pSiS->NoHostBus = FALSE; +/* pSiS->UsePCIRetry = TRUE; */ + pSiS->TurboQueue = TRUE; + pSiS->HWCursor = TRUE; + pSiS->Rotate = FALSE; + pSiS->ShadowFB = FALSE; + pSiS->VESA = -1; + pSiS->NoXvideo = FALSE; + pSiS->maxxfbmem = 0; + pSiS->forceCRT1 = -1; + pSiS->DSTN = FALSE; + pSiS->FSTN = FALSE; + pSiS->XvOnCRT2 = FALSE; + pSiS->NoYV12 = -1; + pSiS->PDC = -1; + pSiS->OptTVStand = -1; + pSiS->OptROMUsage = -1; + pSiS->noInternalModes = FALSE; + pSiS->OptUseOEM = -1; + pSiS->OptTVOver = -1; + pSiS->OptTVSOver = -1; + pSiS->chtvlumabandwidthcvbs = -1; + pSiS->chtvlumabandwidthsvideo = -1; + pSiS->chtvlumaflickerfilter = -1; + pSiS->chtvchromabandwidth = -1; + pSiS->chtvchromaflickerfilter = -1; + pSiS->chtvcvbscolor = -1; + pSiS->chtvtextenhance = -1; + pSiS->chtvcontrast = -1; + pSiS->sistvedgeenhance = -1; + pSiS->sistvantiflicker = -1; + pSiS->sistvsaturation = -1; + pSiS->sistvcfilter = -1; + pSiS->sistvyfilter = 1; /* 0 = off, 1 = default, 2-8 = filter no */ + pSiS->sistvcolcalibc = 0; + pSiS->sistvcolcalibf = 0; + pSiS->sis6326enableyfilter = -1; + pSiS->sis6326yfilterstrong = -1; + pSiS->sis6326tvplug = -1; + pSiS->sis6326fscadjust = 0; + pSiS->tvxpos = 0; + pSiS->tvypos = 0; + pSiS->tvxscale = 0; + pSiS->tvyscale = 0; + pSiS->NonDefaultPAL = -1; + pSiS->chtvtype = -1; + pSiS->restorebyset = TRUE; + pSiS->nocrt2ddcdetection = FALSE; + pSiS->forcecrt2redetection = FALSE; + pSiS->ForceCRT2Type = CRT2_DEFAULT; + pSiS->ForceTVType = -1; + pSiS->CRT1gamma = TRUE; + pSiS->CRT2gamma = TRUE; + pSiS->enablesisctrl = FALSE; + pSiS->XvDefBri = 0; + pSiS->XvDefCon = 4; + pSiS->XvDefHue = 0; + pSiS->XvDefSat = 0; + pSiS->XvDefDisableGfx = FALSE; + pSiS->XvDefDisableGfxLR = FALSE; + pSiS->UsePanelScaler = -1; + pSiS->XvUseMemcpy = TRUE; + pSiS->XvUseChromaKey = FALSE; + pSiS->XvDisableColorKey = FALSE; + pSiS->XvInsideChromaKey = FALSE; + pSiS->XvYUVChromaKey = FALSE; + pSiS->XvChromaMin = 0x000101fe; + pSiS->XvChromaMax = 0x000101ff; + pSiS->GammaBriR = pSiS->GammaBriG = pSiS->GammaBriB = 1000; + pSiS->GammaPBriR = pSiS->GammaPBriG = pSiS->GammaPBriB = 1000; +#ifdef SISMERGED + pSiS->MergedFB = FALSE; + pSiS->CRT2Position = sisRightOf; + pSiS->CRT2HSync = NULL; + pSiS->CRT2VRefresh = NULL; + pSiS->MetaModes = NULL; +#ifdef SISXINERAMA + pSiS->UseSiSXinerama = TRUE; + pSiS->CRT2IsScrn0 = FALSE; +#endif +#endif +#ifdef SIS_CP + SIS_CP_OPT_DEFAULT +#endif - /* Collect all of the relevant option flags (fill in pScrn->options) */ - xf86CollectOptions(pScrn, NULL); + /* Chipset dependent defaults */ - /* Process the options */ - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, SISOptions); + if(pSiS->Chipset == PCI_CHIP_SIS530) { + /* TW: TQ still broken on 530/620? */ + pSiS->TurboQueue = FALSE; + } + + if(pSiS->Chipset == PCI_CHIP_SIS6326) { + pSiS->newFastVram = 1; + } + +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + pSiS->OptUseColorCursor = 0; +#else + if(pSiS->VGAEngine == SIS_300_VGA) { + pSiS->OptUseColorCursor = 0; + pSiS->OptUseColorCursorBlend = 1; + pSiS->OptColorCursorBlendThreshold = 0x37000000; + } else if(pSiS->VGAEngine == SIS_315_VGA) { + pSiS->OptUseColorCursor = 1; + } +#endif + if(pSiS->VGAEngine == SIS_300_VGA) { + pSiS->AllowHotkey = 0; + } else if(pSiS->VGAEngine == SIS_315_VGA) { + pSiS->AllowHotkey = 1; + } + + /* Collect the options */ - from = X_DEFAULT; - if (pScrn->depth <= 8) { #if 0 - if (xf86GetOptValInteger(SISOptions, OPTION_RGB_BITS, - &pScrn->rgbBits)) - { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Bits per RGB set to %d\n", pScrn->rgbBits); + /* PCI retry - What the heck is/was this for? */ + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_PCI_RETRY, &pSiS->UsePCIRetry)) { + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "PCI retry %s\n", + pSiS->UsePCIRetry ? enabledstr : disabledstr); +#endif + + /* Mem clock */ +#if 0 /* This is not used */ + if(xf86GetOptValFreq(pSiS->Options, OPTION_SET_MEMCLOCK, OPTUNITS_MHZ, + &temp)) { + pSiS->MemClock = (int)(temp * 1000.0); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Memory clock set to %.3f MHz\n", pSiS->MemClock/1000.0); + } +#endif + + /* FastVRAM (5597/5598, 6326 and 530/620 only) + */ + if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) { + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_FAST_VRAM, &pSiS->newFastVram)) { + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Fast VRAM %s\n", + (pSiS->newFastVram == -1) ? + ((pSiS->oldChipset == OC_SIS620) ? "enabled (for read only)" : + "enabled (for write only)") : + (pSiS->newFastVram ? "enabled (for read and write)" : disabledstr)); + } + + /* NoHostBus (5597/5598 only) + */ + if((pSiS->Chipset == PCI_CHIP_SIS5597)) { + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_NOHOSTBUS, &pSiS->NoHostBus)) { + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "SiS5597/5598 VGA-to-CPU host bus %s\n", + pSiS->NoHostBus ? disabledstr : enabledstr); + } + + /* MaxXFBMem + * This options limits the amount of video memory X uses for screen + * and off-screen buffers. This option should be used if using DRI + * is intended. The kernel framebuffer driver required for DRM will + * start its memory heap at 12MB if it detects more than 16MB, at 8MB if + * between 8 and 16MB are available, otherwise at 4MB. So, if the amount + * of memory X uses, a clash between the framebuffer's memory heap + * and X is avoided. The amount is to be specified in KB. + */ + if(xf86GetOptValULong(pSiS->Options, OPTION_MAXXFBMEM, + &pSiS->maxxfbmem)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "MaxXFBMem: Framebuffer memory shall be limited to %d KB\n", + pSiS->maxxfbmem); + pSiS->maxxfbmem *= 1024; + } + + /* NoAccel + * Turns off 2D acceleration + */ + if(xf86ReturnOptValBool(pSiS->Options, OPTION_NOACCEL, FALSE)) { + pSiS->NoAccel = TRUE; +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + pSiS->NoXvideo = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "2D Acceleration and Xv disabled\n"); +#else + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "2D Acceleration disabled\n"); +#endif + + } + + /* SWCursor + * HWCursor + * Chooses whether to use the hardware or software cursor + */ + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_HW_CURSOR, &pSiS->HWCursor)) { + from = X_CONFIG; + } + if(xf86ReturnOptValBool(pSiS->Options, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pSiS->HWCursor = FALSE; + pSiS->OptUseColorCursor = 0; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pSiS->HWCursor ? "HW" : "SW"); + + /* + * UseColorHWCursor + * ColorHWCursorBlending + * ColorHWCursorBlendThreshold + * + * Enable/disable color hardware cursors; + * enable/disable color hw cursor emulation for 300 series + * select emultation transparency threshold for 300 series + * + */ +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) +#ifdef ARGB_CURSOR +#ifdef SIS_ARGB_CURSOR + if((pSiS->HWCursor) && ((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA))) { + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_USERGBCURSOR, &pSiS->OptUseColorCursor)) { + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Color HW cursor is %s\n", + pSiS->OptUseColorCursor ? enabledstr : disabledstr); + + if(pSiS->VGAEngine == SIS_300_VGA) { + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_USERGBCURSORBLEND, &pSiS->OptUseColorCursorBlend)) { + from = X_CONFIG; + } + if(pSiS->OptUseColorCursor) { + xf86DrvMsg(pScrn->scrnIndex, from, + "HW cursor color blending emulation is %s\n", + (pSiS->OptUseColorCursorBlend) ? enabledstr : disabledstr); + } + { + int temp; + from = X_DEFAULT; + if(xf86GetOptValInteger(pSiS->Options, OPTION_USERGBCURSORBLENDTH, &temp)) { + if((temp >= 0) && (temp <= 255)) { + from = X_CONFIG; + pSiS->OptColorCursorBlendThreshold = (temp << 24); + } else { + temp = pSiS->OptColorCursorBlendThreshold >> 24; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Illegal color HW cursor blending threshold, valid range 0-255\n"); + } + } else { + temp = pSiS->OptColorCursorBlendThreshold >> 24; + } + if(pSiS->OptUseColorCursor) { + if(pSiS->OptUseColorCursorBlend) { + xf86DrvMsg(pScrn->scrnIndex, from, + "HW cursor color blending emulation threshold is %d\n", temp); + } + } + } + } + } +#endif +#endif +#endif + + /* + * MergedFB + * + * Enable/disable and configure merged framebuffer mode + * + */ +#ifdef SISMERGED +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + Bool val; + if(xf86GetOptValBool(pSiS->Options, OPTION_MERGEDFB, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Option \"MergedFB\" cannot be used in Dual Head mode\n"); + } + } else +#endif + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + Bool val; + if(xf86GetOptValBool(pSiS->Options, OPTION_MERGEDFB, &val)) { + if(val) pSiS->MergedFB = TRUE; + } else if(xf86GetOptValBool(pSiS->Options, OPTION_MERGEDFB2, &val)) { + if(val) pSiS->MergedFB = TRUE; + } + + if(pSiS->MergedFB) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2POS); + if(!strptr) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2POS2); + } + if(strptr) { + if(!xf86NameCmp(strptr,"LeftOf")) { + pSiS->CRT2Position = sisLeftOf; +#ifdef SISXINERAMA + pSiS->CRT2IsScrn0 = TRUE; +#endif + } else if(!xf86NameCmp(strptr,"RightOf")) { + pSiS->CRT2Position = sisRightOf; +#ifdef SISXINERAMA + pSiS->CRT2IsScrn0 = FALSE; +#endif + } else if(!xf86NameCmp(strptr,"Above")) { + pSiS->CRT2Position = sisAbove; +#ifdef SISXINERAMA + pSiS->CRT2IsScrn0 = FALSE; +#endif + } else if(!xf86NameCmp(strptr,"Below")) { + pSiS->CRT2Position = sisBelow; +#ifdef SISXINERAMA + pSiS->CRT2IsScrn0 = TRUE; +#endif + } else if(!xf86NameCmp(strptr,"Clone")) { + pSiS->CRT2Position = sisClone; +#ifdef SISXINERAMA + pSiS->CRT2IsScrn0 = TRUE; +#endif + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "CRT2Position"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid parameters are \"RightOf\", \"LeftOf\", \"Above\", \"Below\", or \"Clone\"\n"); + } + } + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_METAMODES); + if(strptr) { + pSiS->MetaModes = xalloc(strlen(strptr) + 1); + if(pSiS->MetaModes) memcpy(pSiS->MetaModes, strptr, strlen(strptr) + 1); + } + if(pSiS->MetaModes) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2HSYNC); + if(!strptr) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2HSYNC2); + } + if(strptr) { + pSiS->CRT2HSync = xalloc(strlen(strptr) + 1); + if(pSiS->CRT2HSync) memcpy(pSiS->CRT2HSync, strptr, strlen(strptr) + 1); + } + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2VREFRESH); + if(!strptr) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2VREFRESH2); + } + if(strptr) { + pSiS->CRT2VRefresh = xalloc(strlen(strptr) + 1); + if(pSiS->CRT2VRefresh) memcpy(pSiS->CRT2VRefresh, strptr, strlen(strptr) + 1); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Option \"MergedFB\" (alias \"TwinView\") requires Option \"MetaModes\".\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "MergedFB (alias TwinView) mode disabled.\n"); + pSiS->MergedFB = FALSE; + } +#ifdef SISXINERAMA + if(pSiS->MergedFB) { + if(xf86GetOptValBool(pSiS->Options, OPTION_NOSISXINERAMA, &val)) { + if(val) pSiS->UseSiSXinerama = FALSE; + } else if(xf86GetOptValBool(pSiS->Options, OPTION_NOSISXINERAMA2, &val)) { + if(val) pSiS->UseSiSXinerama = FALSE; + } + if(pSiS->UseSiSXinerama) { + if(xf86GetOptValBool(pSiS->Options, OPTION_CRT2ISSCRN0, &val)) { + pSiS->CRT2IsScrn0 = val ? TRUE : FALSE; + } + } + } +#endif + } + } +#endif + + /* Some options can only be specified in the Master Head's Device + * section. Here we give the user a hint in the log. + */ +#ifdef SISDUALHEAD + if((pSiS->DualHeadMode) && (pSiS->SecondHead)) { + static const char *mystring = "Option \"%s\" is only accepted in Master Head's device section\n"; + Bool val; + int vali; + if(pSiS->VGAEngine != SIS_315_VGA) { + if(xf86GetOptValBool(pSiS->Options, OPTION_TURBOQUEUE, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "TurboQueue"); + } + } + if(xf86GetOptValBool(pSiS->Options, OPTION_RESTOREBYSET, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "RestoreBySetMode"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_ENABLEHOTKEY, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "EnableHotKey"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_ENABLESISCTRL, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "EnableSiSCtrl"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_USEROMDATA, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "UseROMData"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_USEOEM, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "UseOEMData"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_FORCECRT1, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "ForceCRT1"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_NODDCFORCRT2, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "NoCRT2Detection"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_FORCECRT2REDETECTION, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "ForceCRT2ReDetection"); + } + if(xf86GetOptValString(pSiS->Options, OPTION_FORCE_CRT2TYPE)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "ForceCRT2Type"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_SCALELCD, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "ScaleLCD"); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_PDC, &vali)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "PanelDelayCompensation"); + } + if(xf86GetOptValString(pSiS->Options, OPTION_SPECIALTIMING)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "SpecialTiming"); + } + if(xf86GetOptValString(pSiS->Options, OPTION_TVSTANDARD)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "TVStandard"); + } + if(xf86GetOptValString(pSiS->Options, OPTION_CHTVTYPE)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "CHTVType"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVOVERSCAN, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "CHTVOverscan"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVSOVERSCAN, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "CHTVSuperOverscan"); + } + if((xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHCVBS, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHSVIDEO, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMAFLICKERFILTER, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMABANDWIDTH, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMAFLICKERFILTER, &vali)) || + (xf86GetOptValBool(pSiS->Options, OPTION_CHTVCVBSCOLOR, &val)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_CHTVTEXTENHANCE, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCONTRAST, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_SISTVEDGEENHANCE, &vali)) || + (xf86GetOptValString(pSiS->Options, OPTION_SISTVANTIFLICKER)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_SISTVSATURATION, &vali)) || + (xf86GetOptValBool(pSiS->Options, OPTION_SISTVCHROMAFILTER, &val)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_SISTVLUMAFILTER, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_SISTVCOLCALIBCOARSE, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_SISTVCOLCALIBFINE, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_TVXPOSOFFSET, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_TVYPOSOFFSET, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_TVXSCALE, &vali)) || + (xf86GetOptValInteger(pSiS->Options, OPTION_TVYSCALE, &vali))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "TV related options are only accepted in Master Head's device section"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_CRT1GAMMA, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "CRT1Gamma"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_CRT2GAMMA, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "CRT2Gamma"); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_XVONCRT2, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "XvOnCRT2"); + } +#ifdef SIS_CP + SIS_CP_OPT_DH_WARN +#endif + } else +#endif + { + if(pSiS->VGAEngine != SIS_315_VGA) { + + /* TurboQueue + * We always use this on 315 series. + */ + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_TURBOQUEUE, &pSiS->TurboQueue)) { + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "TurboQueue %s\n", + pSiS->TurboQueue ? enabledstr : disabledstr); + } + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + + Bool val; + + /* RestoreBySetMode (300/315/330 series only) + * Set this to force the driver to set the old mode instead of restoring + * the register contents. This can be used to overcome problems with + * LCD panels and video bridges. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_RESTOREBYSET, &val)) { + pSiS->restorebyset = val ? TRUE : FALSE; + } + + /* EnableHotkey (300/315/330 series only) + * Enables or disables the BIOS hotkey switch for + * switching the output device on laptops. + * This key causes a total machine hang on many 300 series + * machines, it is therefore by default disabled on such. + * In dual head mode, using the hotkey is lethal, so we + * forbid it then in any case. + * However, although the driver disables the hotkey as + * BIOS developers intented to do that, some buggy BIOSes + * still cause the machine to freeze. Hence the warning. + */ + { + int flag = 0; +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiS->AllowHotkey = 0; + flag = 1; + } else +#endif + if(xf86GetOptValBool(pSiS->Options, OPTION_ENABLEHOTKEY, &val)) { + pSiS->AllowHotkey = val ? 1 : 0; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hotkey display switching is %s%s\n", + pSiS->AllowHotkey ? enabledstr : disabledstr, + flag ? " in dual head mode" : ""); + if(pSiS->Chipset == PCI_CHIP_SIS630 || + pSiS->Chipset == PCI_CHIP_SIS650 || + pSiS->Chipset == PCI_CHIP_SIS660) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "WARNING: Using the Hotkey might freeze your machine, regardless\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "\twhether enabled or disabled. This is no driver bug.\n"); + } + } + + /* UseROMData (300/315/330 series only) + * This option is enabling/disabling usage of some machine + * specific data from the BIOS ROM. This option can - and + * should - be used in case the driver makes problems + * because SiS changed the location of this data. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_USEROMDATA, &val)) { + pSiS->OptROMUsage = val ? 1 : 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Video ROM data usage shall be %s\n", + val ? enabledstr : disabledstr); + } + + /* UseOEMData (300/315/330 series only) + * The driver contains quite a lot data for OEM LCD panels + * and TV connector specifics which override the defaults. + * If this data is incorrect, the TV may lose color and + * the LCD panel might show some strange effects. Use this + * option to disable the usage of this data. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_USEOEM, &val)) { + pSiS->OptUseOEM = val ? 1 : 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Internal LCD/TV/VGA2 OEM data usage shall be %s\n", + val ? enabledstr : disabledstr); + } + + /* ForceCRT1 (300/315/330 series only) + * This option can be used to force CRT1 to be switched on/off. Its + * intention is mainly for old monitors that can't be detected + * automatically. This is only useful on machines with a video bridge. + * In normal cases, this option won't be necessary. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_FORCECRT1, &val)) { + pSiS->forceCRT1 = val ? 1 : 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "CRT1 shall be forced to %s\n", + val ? "ON" : "OFF"); + } + + /* NoCRT2DDCDetection (315/330 series only) + * If set to true, this disables CRT2 detection using DDC. This is + * to avoid problems with not entirely DDC compiant LCD panels or + * VGA monitors connected to the secondary VGA plug. Since LCD and + * VGA share the same DDC channel, it might in some cases be impossible + * to determine if the device is a CRT monitor or a flat panel. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_NODDCFORCRT2, &val)) { + pSiS->nocrt2ddcdetection = val ? TRUE : FALSE; + } + + /* ForceCRT2ReDetection (315/330 series only) + * If set to true, it forces re-detection of the LCD panel and + * a secondary VGA connection even if the BIOS already had found + * about it. This is meant for custom panels (ie such with + * non-standard resolutions) which the BIOS will "detect" according + * to the established timings, resulting in only a very vague idea + * about the panels real resolution. As for secondary VGA, this + * enables us to include a Plasma panel's proprietary modes. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_FORCECRT2REDETECTION, &val)) { + if(val) { + pSiS->forcecrt2redetection = TRUE; + pSiS->nocrt2ddcdetection = FALSE; + } else pSiS->forcecrt2redetection = FALSE; + } + + /* ForceCRT2Type (300/315/330 series only) + * Used for forcing the driver to initialize a given + * CRT2 device type. + * (SVIDEO, COMPOSITE and SCART for overriding detection) + */ + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_FORCE_CRT2TYPE); + if(strptr != NULL) { + if(!xf86NameCmp(strptr,"TV")) + pSiS->ForceCRT2Type = CRT2_TV; + else if(!xf86NameCmp(strptr,"SVIDEO")) { + pSiS->ForceCRT2Type = CRT2_TV; + pSiS->ForceTVType = TV_SVIDEO; + } else if(!xf86NameCmp(strptr,"COMPOSITE")) { + pSiS->ForceCRT2Type = CRT2_TV; + pSiS->ForceTVType = TV_AVIDEO; + } else if(!xf86NameCmp(strptr,"SCART")) { + pSiS->ForceCRT2Type = CRT2_TV; + pSiS->ForceTVType = TV_SCART; + } else if((!xf86NameCmp(strptr,"LCD")) || (!xf86NameCmp(strptr,"DVI-D"))) + pSiS->ForceCRT2Type = CRT2_LCD; + else if((!xf86NameCmp(strptr,"VGA")) || (!xf86NameCmp(strptr,"DVI-A"))) + pSiS->ForceCRT2Type = CRT2_VGA; + else if(!xf86NameCmp(strptr,"NONE")) + pSiS->ForceCRT2Type = 0; + else if(pSiS->Chipset == PCI_CHIP_SIS550) { + if(!xf86NameCmp(strptr,"DSTN")) { + pSiS->ForceCRT2Type = CRT2_LCD; + pSiS->DSTN = TRUE; + } else if(!xf86NameCmp(strptr,"FSTN")) { + pSiS->ForceCRT2Type = CRT2_LCD; + pSiS->FSTN = TRUE; } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "ForceCRT2Type"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid parameters are \"LCD\" (=\"DVI-D\"), \"TV\", \"SVIDEO\", \"COMPOSITE\",\n" + "\t\"SCART\", \"VGA\" (=\"DVI-A\") or \"NONE\", on the SiS550 also \"DSTN\"\n" + "\tand \"FSTN\"\n"); + } + + if(pSiS->ForceCRT2Type != CRT2_DEFAULT) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "CRT2 type shall be %s\n", strptr); + } + + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SPECIALTIMING); + if(strptr != NULL) { + int i = 0; + BOOLEAN found = FALSE; + if(!xf86NameCmp(strptr,"NONE")) { + pSiS->SiS_Pr->SiS_CustomT = CUT_FORCENONE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Special timing disabled\n"); + } else { + while(mycustomttable[i].chipID != 0) { + if(!xf86NameCmp(strptr,mycustomttable[i].optionName)) { + pSiS->SiS_Pr->SiS_CustomT = mycustomttable[i].SpecialID; + found = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Special timing for %s %s forced\n", + mycustomttable[i].vendorName, mycustomttable[i].cardName); + break; + } + i++; + } + if(!found) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "SpecialTiming"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid parameters are:\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t\"NONE\" (to disable special timings)\n"); + i = 0; + while(mycustomttable[i].chipID != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\t\"%s\" (for %s %s)\n", + mycustomttable[i].optionName, + mycustomttable[i].vendorName, + mycustomttable[i].cardName); + i++; + } + } + } + } + + /* EnableSiSCtrl */ + /* Allow sisctrl tool to change driver settings */ + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_ENABLESISCTRL, &val)) { + if(val) pSiS->enablesisctrl = TRUE; + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "SiSCtrl utility interface is %s\n", + pSiS->enablesisctrl ? enabledstr : disabledstr); + + /* ScaleLCD (300/315/330 series only) + * Can be used to force the bridge/panel link to [do|not do] the + * scaling of modes lower than the panel's native resolution. + * Setting this to TRUE will force the bridge/panel link + * to scale; FALSE will rely on the panel's capabilities. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_SCALELCD, &val)) { + pSiS->UsePanelScaler = val ? 0 : 1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "LCD scaling is %s\n", + pSiS->UsePanelScaler ? disabledstr : enabledstr); + } + + /* PanelDelayCompensation (300/315/330 series only; currently used + * on 300 series only) + * This might be required if the LCD panel shows "small waves". + * The parameter is an integer, usually either 4, 32 or 24. + * Why this option? Simply because SiS did poor BIOS design. + * The PDC value depends on the very LCD panel used in a + * particular machine. For most panels, the driver is able + * to detect the correct value. However, some panels require + * a different setting. The value given must be within the mask 0x3c. + */ + if(xf86GetOptValInteger(pSiS->Options, OPTION_PDC, &pSiS->PDC)) { + if(pSiS->PDC & ~0x3c) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Illegal PanelDelayCompensation parameter\n"); + pSiS->PDC = -1; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Panel delay compensation shall be %d\n", + pSiS->PDC); + } + } + + } + + + /* TVStandard (300/315/330 series and 6326 w/ TV only) + * This option is for overriding the autodetection of + * the BIOS/Jumper option for PAL / NTSC + */ + if((pSiS->VGAEngine == SIS_300_VGA) || + (pSiS->VGAEngine == SIS_315_VGA) || + ((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV))) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_TVSTANDARD); + if(strptr != NULL) { + if(!xf86NameCmp(strptr,"PAL")) + pSiS->OptTVStand = 1; + else if((!xf86NameCmp(strptr,"PALM")) || + (!xf86NameCmp(strptr,"PAL-M"))) { + pSiS->OptTVStand = 1; + pSiS->NonDefaultPAL = 1; + } else if((!xf86NameCmp(strptr,"PALN")) || + (!xf86NameCmp(strptr,"PAL-N"))) { + pSiS->OptTVStand = 1; + pSiS->NonDefaultPAL = 0; + } else if(!xf86NameCmp(strptr,"NTSC")) + pSiS->OptTVStand = 0; + else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "TVStandard"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid parameters are \"PAL\", \"PALM\", \"PALN\" or \"NTSC\"\n"); + } + + if(pSiS->OptTVStand != -1) { + static const char *tvstdstr = "TV standard shall be %s\n"; + if(pSiS->Chipset == PCI_CHIP_SIS6326) { + pSiS->NonDefaultPAL = -1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, tvstdstr, + pSiS->OptTVStand ? "PAL" : "NTSC"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, tvstdstr, + (pSiS->OptTVStand ? + ( (pSiS->NonDefaultPAL == -1) ? "PAL" : + ((pSiS->NonDefaultPAL) ? "PALM" : "PALN") ) + : "NTSC")); + } + } + } + } + + /* CHTVType (315/330 series only) + * Used for telling the driver if the TV output shall + * be i480 HDTV or SCART. + */ + if(pSiS->VGAEngine == SIS_315_VGA) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CHTVTYPE); + if(strptr != NULL) { + if(!xf86NameCmp(strptr,"SCART")) + pSiS->chtvtype = 1; + else if(!xf86NameCmp(strptr,"HDTV")) + pSiS->chtvtype = 0; + else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "CHTVType"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid parameters are \"SCART\" or \"HDTV\"\n"); + } + if(pSiS->chtvtype != -1) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Chrontel: TV type shall be %s\n", strptr); + } + } + + /* CHTVOverscan (300/315/330 series only) + * CHTVSuperOverscan (300/315/330 series only) + * These options are for overriding the BIOS option for + * TV Overscan. Some BIOS don't even have such an option. + * SuperOverscan is only supported with PAL. + * Both options are only effective on machines with a + * CHRONTEL TV encoder. SuperOverscan is only available + * on the 700x. + */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + Bool val; + if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVOVERSCAN, &val)) { + pSiS->OptTVOver = val ? 1 : 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Chrontel: TV overscan shall be %s\n", + val ? enabledstr : disabledstr); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVSOVERSCAN, &pSiS->OptTVSOver)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Chrontel: TV super overscan shall be %s\n", + pSiS->OptTVSOver ? enabledstr : disabledstr); + } + } + + /* Various parameters for TV output via SiS bridge, Chrontel or SiS6326 + */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + int tmp = 0; + xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHCVBS, + &pSiS->chtvlumabandwidthcvbs); + xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHSVIDEO, + &pSiS->chtvlumabandwidthsvideo); + xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMAFLICKERFILTER, + &pSiS->chtvlumaflickerfilter); + xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMABANDWIDTH, + &pSiS->chtvchromabandwidth); + xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMAFLICKERFILTER, + &pSiS->chtvchromaflickerfilter); + xf86GetOptValBool(pSiS->Options, OPTION_CHTVCVBSCOLOR, + &pSiS->chtvcvbscolor); + xf86GetOptValInteger(pSiS->Options, OPTION_CHTVTEXTENHANCE, + &pSiS->chtvtextenhance); + xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCONTRAST, + &pSiS->chtvcontrast); + xf86GetOptValInteger(pSiS->Options, OPTION_SISTVEDGEENHANCE, + &pSiS->sistvedgeenhance); + xf86GetOptValInteger(pSiS->Options, OPTION_SISTVSATURATION, + &pSiS->sistvsaturation); + xf86GetOptValInteger(pSiS->Options, OPTION_SISTVLUMAFILTER, + &pSiS->sistvyfilter); + if((pSiS->sistvyfilter < 0) || (pSiS->sistvyfilter > 8)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Illegal Y Filter number; valid is 0 (off), 1 (default), 2-8 (filter number 1-7)\n"); + pSiS->sistvyfilter = 1; + } + xf86GetOptValBool(pSiS->Options, OPTION_SISTVCHROMAFILTER, + &pSiS->sistvcfilter); + xf86GetOptValInteger(pSiS->Options, OPTION_SISTVCOLCALIBCOARSE, + &pSiS->sistvcolcalibc); + xf86GetOptValInteger(pSiS->Options, OPTION_SISTVCOLCALIBFINE, + &pSiS->sistvcolcalibf); + if((pSiS->sistvcolcalibf > 127) || (pSiS->sistvcolcalibf < -128) || + (pSiS->sistvcolcalibc > 120) || (pSiS->sistvcolcalibc < -120)) { + pSiS->sistvcolcalibf = pSiS->sistvcolcalibc = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Illegal Color Calibration. Range is -128 to 127 (fine), -120 to 120 (coarse)\n"); + } + xf86GetOptValInteger(pSiS->Options, OPTION_TVXPOSOFFSET, + &pSiS->tvxpos); + xf86GetOptValInteger(pSiS->Options, OPTION_TVYPOSOFFSET, + &pSiS->tvypos); + if(pSiS->tvxpos > 32) { pSiS->tvxpos = 32; tmp = 1; } + if(pSiS->tvxpos < -32) { pSiS->tvxpos = -32; tmp = 1; } + if(pSiS->tvypos > 32) { pSiS->tvypos = 32; tmp = 1; } + if(pSiS->tvypos < -32) { pSiS->tvypos = -32; tmp = 1; } + if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Illegal TV x or y offset. Range is from -32 to 32\n"); + tmp = 0; + xf86GetOptValInteger(pSiS->Options, OPTION_TVXSCALE, + &pSiS->tvxscale); + xf86GetOptValInteger(pSiS->Options, OPTION_TVYSCALE, + &pSiS->tvyscale); + if(pSiS->tvxscale > 16) { pSiS->tvxscale = 16; tmp = 1; } + if(pSiS->tvxscale < -16) { pSiS->tvxscale = -16; tmp = 1; } + if(pSiS->tvyscale > 3) { pSiS->tvyscale = 3; tmp = 1; } + if(pSiS->tvyscale < -4) { pSiS->tvyscale = -4; tmp = 1; } + if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Illegal TV x or y scaling parameter. Range is from -16 to 16 (X), -4 to 3 (Y)\n"); + } + + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + int tmp = 0; + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SIS6326FORCETVPPLUG); + if(strptr) { + if(!xf86NameCmp(strptr,"COMPOSITE")) + pSiS->sis6326tvplug = 1; + else if(!xf86NameCmp(strptr,"SVIDEO")) + pSiS->sis6326tvplug = 0; + else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "SIS6326TVForcePlug"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid parameters are \"COMPOSITE\" or \"SVIDEO\"\n"); + } + } + xf86GetOptValBool(pSiS->Options, OPTION_SIS6326ENABLEYFILTER, + &pSiS->sis6326enableyfilter); + xf86GetOptValBool(pSiS->Options, OPTION_SIS6326YFILTERSTRONG, + &pSiS->sis6326yfilterstrong); + xf86GetOptValInteger(pSiS->Options, OPTION_TVXPOSOFFSET, + &pSiS->tvxpos); + xf86GetOptValInteger(pSiS->Options, OPTION_TVYPOSOFFSET, + &pSiS->tvypos); + if(pSiS->tvxpos > 16) { pSiS->tvxpos = 16; tmp = 1; } + if(pSiS->tvxpos < -16) { pSiS->tvxpos = -16; tmp = 1; } + if(pSiS->tvypos > 16) { pSiS->tvypos = 16; tmp = 1; } + if(pSiS->tvypos < -16) { pSiS->tvypos = -16; tmp = 1; } + if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Illegal TV x or y offset. Range is from -16 to 16\n"); + xf86GetOptValInteger(pSiS->Options, OPTION_SIS6326FSCADJUST, + &pSiS->sis6326fscadjust); + if(pSiS->sis6326fscadjust) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Adjusting the default FSC by %d\n", + pSiS->sis6326fscadjust); + } + } + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA) || + ((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV))) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SISTVANTIFLICKER); + if(!strptr) { + strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SIS6326ANTIFLICKER); + } + if(strptr) { + if(!xf86NameCmp(strptr,"OFF")) + pSiS->sistvantiflicker = 0; + else if(!xf86NameCmp(strptr,"LOW")) + pSiS->sistvantiflicker = 1; + else if(!xf86NameCmp(strptr,"MED")) + pSiS->sistvantiflicker = 2; + else if(!xf86NameCmp(strptr,"HIGH")) + pSiS->sistvantiflicker = 3; + else if(!xf86NameCmp(strptr,"ADAPTIVE")) + pSiS->sistvantiflicker = 4; + else { + pSiS->sistvantiflicker = -1; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "SISTVAntiFlicker"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid parameters are \"OFF\", \"LOW\", \"MED\", \"HIGH\" or \"ADAPTIVE\"\n"); + } + } + } + + /* CRT1Gamma - disable gamma correction for CRT1 + */ + { + Bool val; + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_CRT1GAMMA, &val)) { + from = X_CONFIG; + pSiS->CRT1gamma = val; + } + xf86DrvMsg(pScrn->scrnIndex, from, "CRT1 gamma correction is %s\n", + pSiS->CRT1gamma ? enabledstr : disabledstr); + } + + /* CRT2Gamma - disable gamma correction for CRT2 + */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + Bool val; + if(xf86GetOptValBool(pSiS->Options, OPTION_CRT2GAMMA, &val)) { + pSiS->CRT2gamma = val; + } + } + +#ifdef SIS_CP + SIS_CP_OPT_DOOPT #endif + + } /* DualHead */ + + /* VESA - DEPRECATED + * This option is for forcing the driver to use + * the VESA BIOS extension for mode switching. + */ + { + Bool val; + + if(xf86GetOptValBool(pSiS->Options, OPTION_VESA, &val)) { + pSiS->VESA = val ? 1 : 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "VESA: VESA usage shall be %s\n", + val ? enabledstr : disabledstr); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "*** Option \"VESA\" is deprecated. *** \n"); } - pSiS->HWCursor = TRUE; - if (xf86GetOptValBool(SISOptions, OPTION_HW_CURSOR, &pSiS->HWCursor)) - from = X_CONFIG; - if (xf86ReturnOptValBool(SISOptions, OPTION_SW_CURSOR, FALSE)) { + } + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + + /* NoInternalModes (300/315/330 series only) + * Since the mode switching code for these chipsets is a + * Asm-to-C translation of BIOS code, we only have timings + * for a pre-defined number of modes. The default behavior + * is to replace XFree's default modes with a mode list + * generated out of the known and supported modes. Use + * this option to disable this. NOT RECOMMENDED. + */ + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_NOINTERNALMODES, &pSiS->noInternalModes)) from = X_CONFIG; - pSiS->HWCursor = FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", - pSiS->HWCursor ? "HW" : "SW"); - if (xf86ReturnOptValBool(SISOptions, OPTION_NOACCEL, FALSE)) { - pSiS->NoAccel = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); - } - if (xf86ReturnOptValBool(SISOptions, OPTION_PCI_RETRY, FALSE)) { - pSiS->UsePCIRetry = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); - } - if (xf86GetOptValFreq(SISOptions, OPTION_SET_MEMCLOCK, OPTUNITS_MHZ, - &temp)) { - pSiS->MemClock = (int)(temp * 1000.0); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Memory clock set to %.3f MHz\n", - pSiS->MemClock/1000.0); - } - if (xf86ReturnOptValBool(SISOptions, OPTION_FAST_VRAM, FALSE)) { - pSiS->FastVram = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Fast VRAM enabled\n"); - } + xf86DrvMsg(pScrn->scrnIndex, from, "Usage of built-in modes is %s\n", + pSiS->noInternalModes ? disabledstr : enabledstr); + } - if (xf86ReturnOptValBool(SISOptions, OPTION_TURBOQUEUE, FALSE)) { - pSiS->TurboQueue = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling TurboQueue\n"); - } + /* ShadowFB */ + from = X_DEFAULT; + if(xf86GetOptValBool(pSiS->Options, OPTION_SHADOW_FB, &pSiS->ShadowFB)) { +#ifdef SISMERGED + if(pSiS->MergedFB) { + pSiS->ShadowFB = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Shadow Frame Buffer not supported in MergedFB mode\n"); + } else +#endif + from = X_CONFIG; + } + if(pSiS->ShadowFB) { + pSiS->NoAccel = TRUE; +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + pSiS->NoXvideo = TRUE; + xf86DrvMsg(pScrn->scrnIndex, from, + "Using \"Shadow Frame Buffer\" - 2D acceleration and Xv disabled\n"); +#else + xf86DrvMsg(pScrn->scrnIndex, from, + "Using \"Shadow Frame Buffer\" - 2D acceleration disabled\n"); +#endif + } + + /* Rotate */ + if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_ROTATE))) { +#ifdef SISMERGED + if(pSiS->MergedFB) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Screen rotation not supported in MergedFB mode\n"); + } else +#endif + if(!xf86NameCmp(strptr, "CW")) { + pSiS->Rotate = 1; + } else if(!xf86NameCmp(strptr, "CCW")) { + pSiS->Rotate = -1; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "Rotate"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid parameters are \"CW\" or \"CCW\"\n"); + } + + if(pSiS->Rotate) { + pSiS->ShadowFB = TRUE; + pSiS->NoAccel = TRUE; + pSiS->HWCursor = FALSE; +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + pSiS->NoXvideo = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen %sclockwise (2D acceleration and Xv disabled)\n", + (pSiS->Rotate == -1) ? "counter " : ""); +#else + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen %sclockwise (2D acceleration disabled)\n", + (pSiS->Rotate == -1) ? "counter " : ""); +#endif + + } + } + + /* NoXVideo + * Set this to TRUE to disable Xv hardware video acceleration + */ +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + if((!pSiS->NoAccel) && (!pSiS->NoXvideo)) { +#else + if(!pSiS->NoXvideo) { +#endif + if(xf86ReturnOptValBool(pSiS->Options, OPTION_NOXVIDEO, FALSE)) { + pSiS->NoXvideo = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XVideo extension disabled\n"); + } + + if(!pSiS->NoXvideo) { + Bool val; + int tmp; + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + /* XvOnCRT2 + * On chipsets with only one overlay (315, 650, 740, 330), the user can + * choose to display the overlay on CRT1 or CRT2. By setting this + * option to TRUE, the overlay will be displayed on CRT2. The + * default is: CRT1 if only CRT1 available, CRT2 if only CRT2 + * available, and CRT1 if both is available and detected. + * Since implementation of the XV_SWITCHCRT Xv property this only + * selects the default CRT. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_XVONCRT2, &val)) { + pSiS->XvOnCRT2 = val ? TRUE : FALSE; + } + } + + if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) { + /* NoYV12 (for 5597/5598, 6326 and 530/620 only) + * YV12 has problems with videos larger than 384x288. So + * allow the user to disable YV12 support to force the + * application to use YUV2 instead. + */ + if(xf86GetOptValBool(pSiS->Options, OPTION_NOYV12, &val)) { + pSiS->NoYV12 = val ? 1 : 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Xv YV12/I420 support is %s\n", + pSiS->NoYV12 ? disabledstr : enabledstr); + } + } + + /* Some Xv properties' defaults can be set by options */ + if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFCONTRAST, &tmp)) { + if((tmp >= 0) && (tmp <= 7)) pSiS->XvDefCon = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "XvDefaultContrast" ,0, 7); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFBRIGHTNESS, &tmp)) { + if((tmp >= -128) && (tmp <= 127)) pSiS->XvDefBri = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "XvDefaultBrightness", -128, 127); + } + if(pSiS->VGAEngine == SIS_315_VGA) { + if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFHUE, &tmp)) { + if((tmp >= -8) && (tmp <= 7)) pSiS->XvDefHue = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "XvDefaultHue", -8, 7); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFSATURATION, &tmp)) { + if((tmp >= -7) && (tmp <= 7)) pSiS->XvDefSat = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "XvDefaultSaturation", -7, 7); + } + } + if(xf86GetOptValBool(pSiS->Options, OPTION_XVDEFDISABLEGFX, &val)) { + if(val) pSiS->XvDefDisableGfx = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Graphics display will be %s during Xv usage\n", + val ? disabledstr : enabledstr); + } + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if(xf86GetOptValBool(pSiS->Options, OPTION_XVDEFDISABLEGFXLR, &val)) { + if(val) pSiS->XvDefDisableGfxLR = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Graphics display left/right of overlay will be %s during Xv usage\n", + val ? disabledstr : enabledstr); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_XVDISABLECOLORKEY, &val)) { + if(val) pSiS->XvDisableColorKey = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Xv Color key is %s\n", + val ? disabledstr : enabledstr); + } + if(xf86GetOptValBool(pSiS->Options, OPTION_XVUSECHROMAKEY, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Xv Chroma-keying is %s\n", + val ? enabledstr : disabledstr); + if(val) pSiS->XvUseChromaKey = TRUE; + } + if(xf86GetOptValBool(pSiS->Options, OPTION_XVINSIDECHROMAKEY, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Xv: Video is transparent if %s chroma key range\n", + val ? "inside" : "outside"); + if(val) pSiS->XvInsideChromaKey = TRUE; + } + if(pSiS->VGAEngine == SIS_300_VGA) { + if(xf86GetOptValBool(pSiS->Options, OPTION_XVYUVCHROMAKEY, &val)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Xv: Chroma key is in %s format\n", + val ? "YUV" : "RGB"); + if(val) pSiS->XvYUVChromaKey = TRUE; + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Xv: Chroma key is of same format as video source\n"); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_XVCHROMAMIN, &tmp)) { + if((tmp >= 0) && (tmp <= 0xffffff)) pSiS->XvChromaMin = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "XvChromaMin", 0, 0xffffff); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_XVCHROMAMAX, &tmp)) { + if((tmp >= 0) && (tmp <= 0xffffff)) pSiS->XvChromaMax = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "XvChromaMax", 0, 0xffffff); + } + } + if(xf86GetOptValBool(pSiS->Options, OPTION_XVMEMCPY, &val)) { + pSiS->XvUseMemcpy = val ? TRUE : FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv will %suse memcpy()\n", + val ? "" : "not "); + } + } + } + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + int tmp; + if(xf86GetOptValInteger(pSiS->Options, OPTION_STOREDBRIR, &tmp)) { + if((tmp >= 100) && (tmp <= 10000)) pSiS->GammaBriR = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "StoredGammaBrightnessRed", 100, 10000); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_STOREDBRIG, &tmp)) { + if((tmp >= 100) && (tmp <= 10000)) pSiS->GammaBriG = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "StoredGammaBrightnessGreen", 100, 10000); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_STOREDBRIB, &tmp)) { + if((tmp >= 100) && (tmp <= 10000)) pSiS->GammaBriB = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "StoredGammaBrightnessBlue", 100, 10000); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_STOREDPBRIR, &tmp)) { + if((tmp >= 100) && (tmp <= 10000)) pSiS->GammaPBriR = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "StoredGammaPreBrightnessRed", 100, 10000); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_STOREDPBRIG, &tmp)) { + if((tmp >= 100) && (tmp <= 10000)) pSiS->GammaPBriG = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "StoredGammaPreBrightnessGreen", 100, 10000); + } + if(xf86GetOptValInteger(pSiS->Options, OPTION_STOREDPBRIB, &tmp)) { + if((tmp >= 100) && (tmp <= 10000)) pSiS->GammaPBriB = tmp; + else xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ilrangestr, + "StoredGammaPreBrightnessBlue", 100, 10000); + } + } } -OptionInfoPtr +const OptionInfoRec * SISAvailableOptions(int chipid, int busid) { return SISOptions; } - diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h index cc86dd422..051898a60 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h @@ -1,33 +1,134 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h,v 1.21 2003/06/10 16:44:20 twini Exp $ */ /* + * 2D Acceleration for SiS300, SiS540, SiS630, SiS730, SiS530, SiS620 + * * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h,v 1.9 1999/07/06 11:38:46 dawes Exp $ */ - -/* 3C4 */ + + +/* For general use --------------------------------------------------------------- */ + +#define inSISREG(base) inb(base) +#define outSISREG(base,val) outb(base,val) +#define orSISREG(base,val) do { \ + unsigned char __Temp = inb(base); \ + outSISREG(base, __Temp | (val)); \ + } while (0) +#define andSISREG(base,val) do { \ + unsigned char __Temp = inb(base); \ + outSISREG(base, __Temp & (val)); \ + } while (0) + +#define inSISIDXREG(base,idx,var) do { \ + outb(base,idx); var=inb((base)+1); \ + } while (0) +#define outSISIDXREG(base,idx,val) do { \ + outb(base,idx); outb((base)+1,val); \ + } while (0) +#define orSISIDXREG(base,idx,val) do { \ + unsigned char __Temp; \ + outb(base,idx); \ + __Temp = inb((base)+1)|(val); \ + outSISIDXREG(base,idx,__Temp); \ + } while (0) +#define andSISIDXREG(base,idx,and) do { \ + unsigned char __Temp; \ + outb(base,idx); \ + __Temp = inb((base)+1)&(and); \ + outSISIDXREG(base,idx,__Temp); \ + } while (0) +#define setSISIDXREG(base,idx,and,or) do { \ + unsigned char __Temp; \ + outb(base,idx); \ + __Temp = (inb((base)+1)&(and))|(or); \ + outSISIDXREG(base,idx,__Temp); \ + } while (0) + +#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) +#define GENMASK(mask) BITMASK(1?mask,0?mask) + +#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask)) +#define SETBITS(val,mask) ((val) << (0?mask)) +#define SETBIT(n) (1<<(n)) + +#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to)) +#define SETVARBITS(var,val,from,to) (((var)&(~(GENMASK(to)))) | \ + GETBITSTR(val,from,to)) +#define GETVAR8(var) ((var)&0xFF) +#define SETVAR8(var,val) (var) = GETVAR8(val) + +#define AROFFSET 0x40 +#define ARROFFSET 0x41 +#define GROFFSET 0x4e +#define SROFFSET 0x44 +#define CROFFSET 0x54 +#define MISCROFFSET 0x4c +#define MISCWOFFSET 0x42 +#define INPUTSTATOFFSET 0x5A +#define PART1OFFSET 0x04 +#define PART2OFFSET 0x10 +#define PART3OFFSET 0x12 +#define PART4OFFSET 0x14 +#define PART5OFFSET 0x16 +#define CAPTUREOFFSET 0x00 +#define VIDEOOFFSET 0x02 +#define COLREGOFFSET 0x48 + +#define SISAR pSiS->RelIO + AROFFSET +#define SISARR pSiS->RelIO + ARROFFSET +#define SISGR pSiS->RelIO + GROFFSET +#define SISSR pSiS->RelIO + SROFFSET +#define SISCR pSiS->RelIO + CROFFSET +#define SISMISCR pSiS->RelIO + MISCROFFSET +#define SISMISCW pSiS->RelIO + MISCWOFFSET +#define SISINPSTAT pSiS->RelIO + INPUTSTATOFFSET +#define SISPART1 pSiS->RelIO + PART1OFFSET +#define SISPART2 pSiS->RelIO + PART2OFFSET +#define SISPART3 pSiS->RelIO + PART3OFFSET +#define SISPART4 pSiS->RelIO + PART4OFFSET +#define SISPART5 pSiS->RelIO + PART5OFFSET +#define SISCAP pSiS->RelIO + CAPTUREOFFSET +#define SISVID pSiS->RelIO + VIDEOOFFSET +#define SISCOLIDX pSiS->RelIO + COLREGOFFSET +#define SISCOLDATA pSiS->RelIO + COLREGOFFSET + 1 +#define SISCOL2IDX SISPART5 +#define SISCOL2DATA SISPART5 + 1 + + +#define vc_index_offset CAPTUREOFFSET /* Video capture - unused */ +#define vc_data_offset (CAPTUREOFFSET + 1) +#define vi_index_offset VIDEOOFFSET +#define vi_data_offset (VIDEOOFFSET + 1) +#define crt2_index_offset PART1OFFSET +#define crt2_port_offset (PART1OFFSET + 1) +#define sr_index_offset SROFFSET +#define sr_data_offset (SROFFSET + 1) +#define cr_index_offset CROFFSET +#define cr_data_offset (CROFFSET + 1) +#define input_stat INPUTSTATOFFSET + +/* For old chipsets (5597/5598, 6326, 530/620) ------------ */ +/* SR (3C4) */ #define BankReg 0x06 #define ClockReg 0x07 #define CPUThreshold 0x08 @@ -37,7 +138,6 @@ #define MMIOEnable 0x0B #define RAMSize 0x0C #define Mode64 0x0C -#define ExtConfStatus0 0x0D #define ExtConfStatus1 0x0E #define ClockBase 0x13 #define LinearAdd0 0x20 @@ -55,153 +155,423 @@ /* 3x4 */ #define Offset 0x13 -#define read_xr(num,var) do {outb(0x3c4, num);var=inb(0x3c5);} while (0) - -/* Definitions for the SIS engine communication. */ +/* SiS Registers for 300, 540, 630, 730, 315, 550, 650, 740 ---------------------- */ + +/* VGA standard register */ +#define Index_SR_Graphic_Mode 0x06 +#define Index_SR_RAMDAC_Ctrl 0x07 +#define Index_SR_Threshold_Ctrl1 0x08 +#define Index_SR_Threshold_Ctrl2 0x09 +#define Index_SR_Misc_Ctrl 0x0F +#define Index_SR_DDC 0x11 +#define Index_SR_Feature_Connector_Ctrl 0x12 +#define Index_SR_DRAM_Sizing 0x14 +#define Index_SR_DRAM_State_Machine_Ctrl 0x15 +#define Index_SR_AGP_PCI_State_Machine 0x21 +#define Index_SR_Internal_MCLK0 0x28 +#define Index_SR_Internal_MCLK1 0x29 +#define Index_SR_Internal_DCLK1 0x2B +#define Index_SR_Internal_DCLK2 0x2C +#define Index_SR_Internal_DCLK3 0x2D +#define Index_SR_Ext_Clock_Sel 0x32 +#define Index_SR_Int_Status 0x34 +#define Index_SR_Int_Enable 0x35 +#define Index_SR_Int_Reset 0x36 +#define Index_SR_Power_On_Trap 0x38 +#define Index_SR_Power_On_Trap2 0x39 +#define Index_SR_Power_On_Trap3 0x3A + +/* video registers (300/630/730/315/550/650/740 only) */ +#define Index_VI_Passwd 0x00 + +/* Video overlay horizontal start/end, unit=screen pixels */ +#define Index_VI_Win_Hor_Disp_Start_Low 0x01 +#define Index_VI_Win_Hor_Disp_End_Low 0x02 +#define Index_VI_Win_Hor_Over 0x03 /* Overflow */ + +/* Video overlay vertical start/end, unit=screen pixels */ +#define Index_VI_Win_Ver_Disp_Start_Low 0x04 +#define Index_VI_Win_Ver_Disp_End_Low 0x05 +#define Index_VI_Win_Ver_Over 0x06 /* Overflow */ + +/* Y Plane (4:2:0) or YUV (4:2:2) buffer start address, unit=word */ +#define Index_VI_Disp_Y_Buf_Start_Low 0x07 +#define Index_VI_Disp_Y_Buf_Start_Middle 0x08 +#define Index_VI_Disp_Y_Buf_Start_High 0x09 + +/* U Plane (4:2:0) buffer start address, unit=word */ +#define Index_VI_U_Buf_Start_Low 0x0A +#define Index_VI_U_Buf_Start_Middle 0x0B +#define Index_VI_U_Buf_Start_High 0x0C + +/* V Plane (4:2:0) buffer start address, unit=word */ +#define Index_VI_V_Buf_Start_Low 0x0D +#define Index_VI_V_Buf_Start_Middle 0x0E +#define Index_VI_V_Buf_Start_High 0x0F + +/* Pitch for Y, UV Planes, unit=word */ +#define Index_VI_Disp_Y_Buf_Pitch_Low 0x10 +#define Index_VI_Disp_UV_Buf_Pitch_Low 0x11 +#define Index_VI_Disp_Y_UV_Buf_Pitch_Middle 0x12 + +/* What is this ? */ +#define Index_VI_Disp_Y_Buf_Preset_Low 0x13 +#define Index_VI_Disp_Y_Buf_Preset_Middle 0x14 + +#define Index_VI_UV_Buf_Preset_Low 0x15 +#define Index_VI_UV_Buf_Preset_Middle 0x16 +#define Index_VI_Disp_Y_UV_Buf_Preset_High 0x17 + +/* Scaling control registers */ +#define Index_VI_Hor_Post_Up_Scale_Low 0x18 +#define Index_VI_Hor_Post_Up_Scale_High 0x19 +#define Index_VI_Ver_Up_Scale_Low 0x1A +#define Index_VI_Ver_Up_Scale_High 0x1B +#define Index_VI_Scale_Control 0x1C + +/* Playback line buffer control */ +#define Index_VI_Play_Threshold_Low 0x1D +#define Index_VI_Play_Threshold_High 0x1E +#define Index_VI_Line_Buffer_Size 0x1F + +/* Destination color key */ +#define Index_VI_Overlay_ColorKey_Red_Min 0x20 +#define Index_VI_Overlay_ColorKey_Green_Min 0x21 +#define Index_VI_Overlay_ColorKey_Blue_Min 0x22 +#define Index_VI_Overlay_ColorKey_Red_Max 0x23 +#define Index_VI_Overlay_ColorKey_Green_Max 0x24 +#define Index_VI_Overlay_ColorKey_Blue_Max 0x25 + +/* Source color key, YUV color space */ +#define Index_VI_Overlay_ChromaKey_Red_Y_Min 0x26 +#define Index_VI_Overlay_ChromaKey_Green_U_Min 0x27 +#define Index_VI_Overlay_ChromaKey_Blue_V_Min 0x28 +#define Index_VI_Overlay_ChromaKey_Red_Y_Max 0x29 +#define Index_VI_Overlay_ChromaKey_Green_U_Max 0x2A +#define Index_VI_Overlay_ChromaKey_Blue_V_Max 0x2B + +/* Contrast enhancement and brightness control */ +#define Index_VI_Contrast_Factor 0x2C /* obviously unused/undefined */ +#define Index_VI_Brightness 0x2D +#define Index_VI_Contrast_Enh_Ctrl 0x2E + +#define Index_VI_Key_Overlay_OP 0x2F + +#define Index_VI_Control_Misc0 0x30 +#define Index_VI_Control_Misc1 0x31 +#define Index_VI_Control_Misc2 0x32 + +/* TW: Subpicture registers */ +#define Index_VI_SubPict_Buf_Start_Low 0x33 +#define Index_VI_SubPict_Buf_Start_Middle 0x34 +#define Index_VI_SubPict_Buf_Start_High 0x35 + +/* TW: What is this ? */ +#define Index_VI_SubPict_Buf_Preset_Low 0x36 +#define Index_VI_SubPict_Buf_Preset_Middle 0x37 + +/* TW: Subpicture pitch, unit=16 bytes */ +#define Index_VI_SubPict_Buf_Pitch 0x38 + +/* TW: Subpicture scaling control */ +#define Index_VI_SubPict_Hor_Scale_Low 0x39 +#define Index_VI_SubPict_Hor_Scale_High 0x3A +#define Index_VI_SubPict_Vert_Scale_Low 0x3B +#define Index_VI_SubPict_Vert_Scale_High 0x3C + +#define Index_VI_SubPict_Scale_Control 0x3D +/* (0x40 = enable/disable subpicture) */ + +/* TW: Subpicture line buffer control */ +#define Index_VI_SubPict_Threshold 0x3E + +/* TW: What is this? */ +#define Index_VI_FIFO_Max 0x3F + +/* TW: Subpicture palette; 16 colors, total 32 bytes address space */ +#define Index_VI_SubPict_Pal_Base_Low 0x40 +#define Index_VI_SubPict_Pal_Base_High 0x41 + +/* I wish I knew how to use these ... */ +#define Index_MPEG_Read_Ctrl0 0x60 /* MPEG auto flip */ +#define Index_MPEG_Read_Ctrl1 0x61 /* MPEG auto flip */ +#define Index_MPEG_Read_Ctrl2 0x62 /* MPEG auto flip */ +#define Index_MPEG_Read_Ctrl3 0x63 /* MPEG auto flip */ + +/* TW: MPEG AutoFlip scale */ +#define Index_MPEG_Ver_Up_Scale_Low 0x64 +#define Index_MPEG_Ver_Up_Scale_High 0x65 + +#define Index_MPEG_Y_Buf_Preset_Low 0x66 +#define Index_MPEG_Y_Buf_Preset_Middle 0x67 +#define Index_MPEG_UV_Buf_Preset_Low 0x68 +#define Index_MPEG_UV_Buf_Preset_Middle 0x69 +#define Index_MPEG_Y_UV_Buf_Preset_High 0x6A + +/* TW: The following registers only exist on the 315 series */ + +/* TW: Bit 16:24 of Y_U_V buf start address (?) */ +#define Index_VI_Y_Buf_Start_Over 0x6B +#define Index_VI_U_Buf_Start_Over 0x6C +#define Index_VI_V_Buf_Start_Over 0x6D + +#define Index_VI_Disp_Y_Buf_Pitch_High 0x6E +#define Index_VI_Disp_UV_Buf_Pitch_High 0x6F + +/* Hue and saturation */ +#define Index_VI_Hue 0x70 +#define Index_VI_Saturation 0x71 + +#define Index_VI_SubPict_Start_Over 0x72 +#define Index_VI_SubPict_Buf_Pitch_High 0x73 + +#define Index_VI_Control_Misc3 0x74 + +/* Bits in Scale control (0x1c) */ +#define VI_Scale_Ctrl_Horiz_DDA 0x20 +#define VI_Scale_Ctrl_Vert_DDA 0x40 + +/* TW: Bits (and helpers) for Index_VI_Control_Misc0 */ +#define VI_Misc0_Enable_Overlay 0x02 +#define VI_Misc0_420_Plane_Enable 0x04 /* Select Plane or Packed mode */ +#define VI_Misc0_422_Enable 0x20 /* Select 422 or 411 mode */ +#define VI_Misc0_Fmt_YVU420P 0x0C /* YUV420 Planar (I420, YV12) */ +#define VI_Misc0_Fmt_YUYV 0x28 /* YUYV Packed (=YUY2) */ +#define VI_Misc0_Fmt_UYVY 0x08 /* (UYVY) */ +#define VI_Misc0_Fmt_YVYU 0x38 /* (YVYU) (315 series only?) */ +#define VI_Misc0_Fmt_NV21 0x5c /* (330 series only?) */ +#define VI_Misc0_Fmt_NV12 0x4c /* (330 series only?) */ +#define VI_Misc0_ChromaKeyRGBYUV 0x40 /* 300 series only: 0 = RGB, 1 = YUV */ + +/* TW: Bits for Index_VI_Control_Misc1 */ +#define VI_Misc1_DisableGraphicsAtOverlay 0x01 /* Disables graphics display in overlay area */ +#define VI_Misc1_BOB_Enable 0x02 /* Enable BOB de-interlacer */ +#define VI_Misc1_Line_Merge 0x04 +#define VI_Misc1_Field_Mode 0x08 /* ? */ +#define VI_Misc1_Non_Interleave 0x10 /* ? 0x20 ? - Odd and Even fields are not interleaved ? */ +#define VI_Misc1_Buf_Addr_Lock 0x20 /* 315 series only? */ +/* #define VI_Misc1_? 0x40 */ +/* #define VI_Misc1_? 0x80 */ + +/* TW: Bits for Index_VI_Control_Misc2 */ +#define VI_Misc2_Select_Video2 0x01 +#define VI_Misc2_Video2_On_Top 0x02 +#define VI_Misc2_DisableGraphics 0x04 /* Disable graphics display entirely (<= 650 only, not >= M650, 651) */ +#define VI_Misc2_Vertical_Interpol 0x08 +#define VI_Misc2_Dual_Line_Merge 0x10 /* dual-overlay chips only; "dual video windows relative line buffer merge" */ +#define VI_Misc2_All_Line_Merge 0x20 /* > 315 only */ +#define VI_Misc2_Auto_Flip_Enable 0x40 +#define VI_Misc2_Video_Reg_Write_Enable 0x80 /* 315 series only? */ + +/* TW: Bits for Index_VI_Control_Misc3 */ +#define VI_Misc3_Submit_Video_1 0x01 /* AKA "address ready" */ +#define VI_Misc3_Submit_Video_2 0x02 /* AKA "address ready" */ +#define VI_Misc3_Submit_SubPict 0x04 /* AKA "address ready" */ + +/* TW: Values for Index_VI_Key_Overlay_OP (0x2F) */ +#define VI_ROP_Never 0x00 +#define VI_ROP_DestKey 0x03 +#define VI_ROP_ChromaKey 0x05 +#define VI_ROP_NotChromaKey 0x0A +#define VI_ROP_Always 0x0F + + +/* video registers (6326 and 530/620) --------------- */ +#define Index_VI6326_Passwd 0x80 + +/* Video overlay horizontal start/end, unit=screen pixels */ +#define Index_VI6326_Win_Hor_Disp_Start_Low 0x81 +#define Index_VI6326_Win_Hor_Disp_End_Low 0x82 +#define Index_VI6326_Win_Hor_Over 0x83 /* Overflow */ + +/* Video overlay vertical start/end, unit=screen pixels */ +#define Index_VI6326_Win_Ver_Disp_Start_Low 0x84 +#define Index_VI6326_Win_Ver_Disp_End_Low 0x85 +#define Index_VI6326_Win_Ver_Over 0x86 /* Overflow */ + +/* Y Plane (4:2:0) or YUV (4:2:2) buffer start address, unit=dword */ +#define Index_VI6326_Disp_Y_Buf_Start_Low 0x8A +#define Index_VI6326_Disp_Y_Buf_Start_Middle 0x8B +#define Index_VI6326_Disp_Capt_Y_Buf_Start_High 0x89 /* 6326: 7:4 display, 3:0 capture */ + /* 530/620: 7:3 display. 2:0 reserved */ +/* End address of Y plane (in 16k unit) - 6326 ONLY */ +#define Index_VI6326_Disp_Y_End 0x8D + +/* U Plane (4:2:0) buffer start address, unit=dword */ +#define Index_VI6326_U_Buf_Start_Low 0xB7 +#define Index_VI6326_U_Buf_Start_Middle 0xB8 + +/* V Plane (4:2:0) buffer start address, unit=dword */ +#define Index_VI6326_V_Buf_Start_Low 0xBA +#define Index_VI6326_V_Buf_Start_Middle 0xBB + +/* U/V plane start address overflow bits 19:16 */ +#define Index_VI6326_UV_Buf_Start_High 0xB9 + +/* Pitch for Y, UV Planes, unit=dword(6326 & 530/620) */ +#define Index_VI6326_Disp_Y_Buf_Pitch_Low 0x8C /* 7:0 */ +#define Index_VI6326_Disp_Y_Buf_Pitch_High 0x8E /* 11:8 (3:0 here) */ + +#define Index_VI6326_Disp_UV_Buf_Pitch_Low 0xBC /* 7:0 */ +#define Index_VI6326_Disp_UV_Buf_Pitch_High 0xBD /* 11:8 (3:0 here) */ + +/* Scaling control registers */ +#define Index_VI6326_Hor_Scale 0x92 +#define Index_VI6326_Hor_Scale_Integer 0x94 +#define Index_VI6326_Ver_Scale 0x93 + +/* Playback line buffer control */ +#define Index_VI6326_Play_Threshold_Low 0x9E +#define Index_VI6326_Play_Threshold_High 0x9F +#define Index_VI6326_Line_Buffer_Size 0xA0 /* 530 & 6326: quad-word */ + +/* Destination color key */ +#define Index_VI6326_Overlay_ColorKey_Red_Min 0x97 +#define Index_VI6326_Overlay_ColorKey_Green_Min 0x96 +#define Index_VI6326_Overlay_ColorKey_Blue_Min 0x95 +#define Index_VI6326_Overlay_ColorKey_Red_Max 0xA3 +#define Index_VI6326_Overlay_ColorKey_Green_Max 0xA2 +#define Index_VI6326_Overlay_ColorKey_Blue_Max 0xA1 + +/* Source color key */ +#define Index_VI6326_Overlay_ChromaKey_Red_Y_Min 0x9C +#define Index_VI6326_Overlay_ChromaKey_Green_U_Min 0x9B +#define Index_VI6326_Overlay_ChromaKey_Blue_V_Min 0x9A +#define Index_VI6326_Overlay_ChromaKey_Red_Y_Max 0xA6 +#define Index_VI6326_Overlay_ChromaKey_Green_U_Max 0xA5 +#define Index_VI6326_Overlay_ChromaKey_Blue_V_Max 0xA4 + +/* Contrast enhancement and brightness control */ +#define Index_VI6326_Contrast_Factor 0xB3 +#define Index_VI6326_Brightness 0xB4 +#define Index_VI6326_Contrast_Enh_Ctrl 0xB5 + +/* Alpha */ +#define Index_VI6326_AlphaGraph 0xA7 +#define Index_VI6326_AlphaVideo 0xA8 + +#define Index_VI6326_Key_Overlay_OP 0xA9 + +#define Index_VI6326_Control_Misc0 0x98 +#define Index_VI6326_Control_Misc1 0x99 /* (Datasheet: 6326 ONLY - not correct?) */ +#define Index_VI6326_Control_Misc3 0x9D +#define Index_VI6326_Control_Misc4 0xB6 +#define Index_VI6326_VideoFormatSelect Index_VI6326_Ver_Scale +#define Index_VI6326_Control_Misc5 0xBE /* (Datasheet: 530/620 ONLY - not correct) */ +#define Index_VI6326_Control_Misc6 0xB2 /* 5597 and 6326 only! */ + +/* TW: What is this? not a register, obviously */ +#define Index_VI6326_FIFO_Max 0x3F + +/* TW: Bits (and helpers) for Index_VI6326_Control_Misc0 */ +#define VI6326_Misc0_EnableCapture 0x01 /* 1 = on, 0 = off (6326 only) */ +#define VI6326_Misc0_EnableOverlay 0x02 /* 1 = on, 0 = off */ +#define VI6326_Misc0_VideoOnly 0x10 /* 1 = video only, 0 = gfx + video */ +#define VI6326_Misc0_CaptureInterlace 0x20 /* 1 = capture data is interlace, 0 = not (6326 only) */ +#define VI6326_Misc0_VideoFormat 0x40 /* 1 = YUV, 0 = RGB */ +#define VI6326_Misc0_FieldPolarity 0x80 /* 1 = *Odd / Even, 0 = Odd / *Even (6326 only) */ + +/* TW: Bits for Index_VI6326_Control_Misc1 (ALL 6326 ONLY) */ +#define VI6326_Misc1_EnableYUVCapture 0x01 /* 0 = RGB, 1 = YUV */ +#define VI6326_Misc1_EnableCaptureDithering 0x02 /* 0 = disable, 1 = enable */ +#define VI6326_Misc1_CaptureFormat555 0x04 /* 1 = 555, 0 = 565 */ +#define VI6326_Misc1_FilterModeMask 0x38 +#define VI6326_Misc1_FilterMode0 0x00 /* 1 */ +#define VI6326_Misc1_FilterMode1 0x08 /* 1/8(1+3z^-1+3z^-2+z^-3)*/ +#define VI6326_Misc1_FilterMode2 0x10 /* 1/4(1+2z^-1+z^-2) */ +#define VI6326_Misc1_FilterMode3 0x18 /* 1/2(1+z^-1) */ +#define VI6326_Misc1_FilterMode4 0x20 /* 1/8(1+2z^-1+2z^-2+2z^-3+z^-4) */ +#define VI6326_Misc1_EnableVBSyncIRQ 0x40 /* 1 = Enable IRQ on vertical blank */ +#define VI6326_Misc1_ClearVBSyncIRQ 0x80 /* Clear pending irq */ + +/* TW: Bits for Index_VI6326_Control_Misc3 */ +#define VI6326_Misc3_UVCaptureFormat 0x01 /* 1 = 2's complement, 0 = CCIR 601 (6326 only) */ +#define VI6326_Misc3_UVOverlayFormat 0x02 /* 1 = 2's complement, 0 = CCIR 601 */ +#define VI6326_Misc3_ChromaKeyFormat 0x04 /* 1 = YUV, 0 = RGB */ +#define VI6326_Misc3_VMIAccess 0x08 /* 1 = enable, 0 = disable (6326 only) */ +#define VI6326_Misc3_VMIEnable 0x10 /* 1 = enable, 0 = disable (6326 only) */ +#define VI6326_Misc3_VMIIRQ 0x20 /* 1 = enable, 0 = disable (6326 only) */ +#define VI6326_Misc3_BT819A 0x40 /* 1 = enable, 0 = disable (6326 only) */ +#define VI6326_Misc3_SystemMemFB 0x80 /* 1 = enable, 0 = disable (6326 only) */ + +/* TW: Bits for Index_VI6326_Control_Misc4 */ +#define VI6326_Misc4_CPUVideoFormatMask 0x03 +#define VI6326_Misc4_CPUVideoFormatRGB555 0x00 +#define VI6326_Misc4_CPUVideoFormatYUV422 0x01 +#define VI6326_Misc4_CPUVideoFormatRGB565 0x02 +#define VI6326_Misc4_EnableYUV420 0x04 /* 1 = enable, 0 = disable */ +/** #define WHATISTHIS 0x40 */ + +/* TW: Bits for Index_VI6326_Control_Misc5 (all 530/620 only) */ +#define VI6326_Misc5_LineBufferMerge 0x10 /* 0 = disable, 1=enable */ +#define VI6326_Misc5_VPlaneBit20 0x04 +#define VI6326_Misc5_UPlaneBit20 0x02 + +/* TW: Bits for Index_VI6326_Control_Misc6 (5597 and 6326 only) */ +#define VI6326_Misc6_Decimation 0x80 /* 0=disable 1=enable video decimation */ + +/* Video format selection */ +#define VI_6326_VideoUYVY422 0x00 +#define VI_6326_VideoVYUY422 0x40 +#define VI_6326_VideoYUYV422 0x80 +#define VI_6326_VideoYVYU422 0xC0 +#define VI_6326_VideoRGB555 0x00 +#define VI_6326_VideoRGB565 0x40 + +/* TW: Values for Index_VI6326_Key_Overlay_OP */ +#define VI6326_ROP_Never 0x00 +#define VI6326_ROP_DestKey 0x03 +#define VI6326_ROP_Always 0x0F + +/* --- end of 6326 video registers ---------------------------------- */ + +/* TW register base (6326 only) */ +#define Index_TV6326_TVOutIndex 0xE0 +#define Index_TV6326_TVOutData 0xE1 -extern int sisReg32MMIO[]; -#define BR(x) sisReg32MMIO[x] - -/* These are done using Memory Mapped IO, of the registers */ -/* - * Modified for Sis by Xavier Ducoin (xavier@rd.lectra.fr) +/* + * CRT_2 function control register --------------------------------- */ +#define Index_CRT2_FC_CONTROL 0x00 +#define Index_CRT2_FC_SCREEN_HIGH 0x04 +#define Index_CRT2_FC_SCREEN_MID 0x05 +#define Index_CRT2_FC_SCREEN_LOW 0x06 +#define Index_CRT2_FC_ENABLE_WRITE 0x24 +#define Index_CRT2_FC_VR 0x25 +#define Index_CRT2_FC_VCount 0x27 +#define Index_CRT2_FC_VCount1 0x28 + +#define Index_310_CRT2_FC_VR 0x30 /* d[1] = vertical retrace */ +#define Index_310_CRT2_FC_RT 0x33 /* d[7] = retrace in progress */ + +/* video attributes - these should probably be configurable on the fly + * so users with different desktop sizes can keep + * captured data off the desktop + */ +#define _VINWID 704 +#define _VINHGT _VINHGT_NTSC +#define _VINHGT_NTSC 240 +#define _VINHGT_PAL 290 +#define _VIN_WINDOW (704 * 291 * 2) +#define _VBI_WINDOW (704 * 64 * 2) +#define _VIN_FIELD_EVEN 1 +#define _VIN_FIELD_ODD 2 +#define _VIN_FIELD_BOTH 4 -#define sisLEFT2RIGHT 0x10 -#define sisRIGHT2LEFT 0x00 -#define sisTOP2BOTTOM 0x20 -#define sisBOTTOM2TOP 0x00 - -#define sisSRCSYSTEM 0x03 -#define sisSRCVIDEO 0x02 -#define sisSRCFG 0x01 -#define sisSRCBG 0x00 - -#define sisCMDBLT 0x0000 -#define sisCMDBLTMSK 0x0100 -#define sisCMDCOLEXP 0x0200 -#define sisCMDLINE 0x0300 - -#define sisCMDENHCOLEXP 0x2000 - -#define sisXINCREASE 0x10 -#define sisYINCREASE 0x20 -#define sisCLIPENABL 0x40 -#define sisCLIPINTRN 0x80 -#define sisCLIPEXTRN 0x00 - - -#define sisPATREG 0x08 -#define sisPATFG 0x04 -#define sisPATBG 0x00 - -#define sisLASTPIX 0x0800 -#define sisXMAJOR 0x0400 - - -/* Macros to do useful things with the SIS BitBLT engine */ - -#define sisBLTSync \ - while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)+2) & \ - (0x4000)){} - -/* According to SiS 6326 2D programming guide, 16 bits position at */ -/* 0x82A8 returns queue free. But this don't work, so don't wait */ -/* anything when turbo-queue is enabled. If there are frequent syncs */ -/* this should work. But not for xaa_benchmark :-( */ - -#define sisBLTWAIT \ - if (!pSiS->TurboQueue) {\ - while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)+2) & \ - (0x4000)){}} /* \ - else {while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)) < \ - 63){}} */ - -#define sisSETPATREG()\ - ((unsigned char *)(pSiS->IOBase + BR(11))) - -#define sisSETPATREGL()\ - ((unsigned long *)(pSiS->IOBase + BR(11))) - -#define sisSETCMD(op) \ - *(volatile unsigned short *)(pSiS->IOBase + BR(10) +2 ) = op - -#define sisSETROPFG(op) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(4)))&0xffffff) | (op<<24) - -#define sisSETROPBG(op) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(5)))&0xffffff) | (op<<24) - -#define sisSETROP(op) \ - sisSETROPFG(op);sisSETROPBG(op); - - -#define sisSETSRCADDR(srcAddr) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = srcAddr&0x3FFFFFL - -#define sisSETDSTADDR(dstAddr) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = dstAddr&0x3FFFFFL - -#define sisSETPITCH(srcPitch,dstPitch) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(2)) = ((dstPitch&0xFFFF)<<16)| \ - (srcPitch&0xFFFF) - -/* according to SIS 2D Engine Programming Guide - * width -1 independant of Bpp - */ -#define sisSETHEIGHTWIDTH(Height,Width)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = (((Height)&0xFFFF)<<16)| \ - ((Width)&0xFFFF) - -#define sisSETCLIPTOP(x,y)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(8)) = (((y)&0xFFFF)<<16)| \ - ((x)&0xFFFF) - -#define sisSETCLIPBOTTOM(x,y)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(9)) = (((y)&0xFFFF)<<16)| \ - ((x)&0xFFFF) - -#define sisSETBGCOLOR(bgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor) - -#define sisSETBGCOLOR8(bgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFF) - -#define sisSETBGCOLOR16(bgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFFFF) - -#define sisSETBGCOLOR24(bgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFFFFFF) - - -#define sisSETFGCOLOR(fgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor) - -#define sisSETFGCOLOR8(fgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFF) - -#define sisSETFGCOLOR16(fgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFFFF) - -#define sisSETFGCOLOR24(fgColor)\ - *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFFFFFF) - -/* Line drawing */ - -#define sisSETXStart(XStart) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = XStart&0xFFFF -#define sisSETYStart(YStart) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = YStart&0xFFFF +/* i2c registers (TW; not on 300/315 series) */ +#define X_INDEXREG 0x14 +#define X_PORTREG 0x15 +#define X_DATA 0x0f +#define I2C_SCL 0x00 +#define I2C_SDA 0x01 +#define I2C_DELAY 10 -#define sisSETLineMajorCount(MajorAxisCount) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = MajorAxisCount&0xFFFF +/* mmio registers for video */ +#define REG_PRIM_CRT_COUNTER 0x8514 -#define sisSETLineSteps(K1,K2) \ - *(volatile unsigned int *)(pSiS->IOBase + BR(6)) = (((K1)&0xFFFF)<<16)| \ - ((K2)&0xFFFF) +/* TW: MPEG MMIO registers (630 and later) ----------------------------------------- */ -#define sisSETLineErrorTerm(ErrorTerm) \ - *(volatile unsigned short *)(pSiS->IOBase + BR(7)) = ErrorTerm +/* Not public (yet?) */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_setup.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_setup.c index 99c62af8f..8b3215d69 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_setup.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_setup.c @@ -1,190 +1,596 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_setup.c,v 1.17 2003/08/07 12:52:23 twini Exp $ */ /* - * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Basic hardware and memory detection + * + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_setup.c,v 1.1 2000/02/12 20:45:37 dawes Exp $ */ - - -#define PSZ 8 -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#include "cfb24_32.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86.h" +#include "fb.h" #include "xf1bpp.h" #include "xf4bpp.h" -#include "mibank.h" -#include "micmap.h" -#include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" #include "xf86_ansic.h" #include "xf86Version.h" -#include "xf86PciInfo.h" -#include "xf86Pci.h" -#include "xf86cmap.h" -#include "vgaHW.h" -#include "xf86RAC.h" - -#include "mipointer.h" -#include "mibstore.h" +#include "xf86cmap.h" -#include "sis_regs.h" #include "sis.h" +#include "sis_regs.h" +#include "sis_dac.h" -#ifdef XFreeXDGA #define _XF86DGA_SERVER_ #include "extensions/xf86dgastr.h" -#endif -#ifdef DPMSExtension #include "globals.h" #define DPMS_SERVER #include "extensions/dpms.h" -#endif -static char *dramTypeStr[] = { - "Fast Page DRAM", - "2 cycle EDO RAM", - "1 cycle EDO RAM", - "SDRAM/SGRAM", - "SDRAM", - "SGRAM", - "ESDRAM" - "" }; +static const char *dramTypeStr[] = { + "Fast Page DRAM", + "2 cycle EDO RAM", + "1 cycle EDO RAM", + "SDRAM/SGRAM", + "SDR SDRAM", + "SGRAM", + "ESDRAM", + "DDR SDRAM", /* for 550/650 */ + "DDR SDRAM", /* for 550/650 */ + "VCM" /* for 630 */ + "" }; + +/* TW: MCLK tables for SiS6326 */ +static const int SiS6326MCLKIndex[4][8] = { + { 10, 12, 14, 16, 17, 18, 19, 7 }, /* SGRAM */ + { 4, 6, 8, 10, 11, 12, 13, 3 }, /* Fast Page */ + { 9, 11, 12, 13, 15, 16, 5, 7 }, /* 2 cycle EDO */ + { 10, 12, 14, 16, 17, 18, 19, 7 } /* ? (Not 1 cycle EDO) */ +}; -static int clockTable[4] = { 66, 75, 83, 100 }; +static const struct _sis6326mclk { + CARD16 mclk; + unsigned char sr13; + unsigned char sr28; + unsigned char sr29; +} SiS6326MCLK[] = { + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 45, 0, 0x2b, 0x26 }, + { 53, 0, 0x49, 0xe4 }, + { 55, 0, 0x7c, 0xe7 }, + { 56, 0, 0x7c, 0xe7 }, + { 60, 0, 0x42, 0xe3 }, + { 61, 0, 0x21, 0xe1 }, + { 65, 0, 0x5a, 0xe4 }, + { 66, 0, 0x5a, 0xe4 }, + { 70, 0, 0x61, 0xe4 }, + { 75, 0, 0x3e, 0xe2 }, + { 80, 0, 0x42, 0xe2 }, + { 83, 0, 0xb3, 0xc5 }, + { 85, 0, 0x5e, 0xe3 }, + { 90, 0, 0xae, 0xc4 }, + {100, 0, 0x37, 0xe1 }, + {115, 0, 0x78, 0x0e }, + {134, 0, 0x4a, 0xa3 } +}; -static void -sisOldChipSetup(ScrnInfoPtr pScrn) +/* For old chipsets, 5597, 6326, 530/620 */ +static void +sisOldSetup(ScrnInfoPtr pScrn) { - int ramsize[4] = {1024, 2048, 4096, 1024}; + SISPtr pSiS = SISPTR(pScrn); + int ramsize[8] = { 1, 2, 4, 0, 0, 2, 4, 8}; + int buswidth[8] = {32, 64, 64, 0, 0, 32, 32, 64 }; + int clockTable[4] = { 66, 75, 83, 100 }; + int ramtype[4] = { 5, 0, 1, 3 }; + int config; + int temp, i; + unsigned char sr23, sr33, sr34, sr37; +#if 0 + unsigned char newsr13, newsr28, newsr29; +#endif + pciConfigPtr pdptr, *systemPCIdevices = NULL; + + if(pSiS->oldChipset <= OC_SIS6225) { + inSISIDXREG(SISSR, 0x0F, temp); + pScrn->videoRam = (1 << (temp & 0x03)) * 1024; + if(pScrn->videoRam > 4096) pScrn->videoRam = 4096; + pSiS->BusWidth = 32; + } else if(pSiS->Chipset == PCI_CHIP_SIS5597) { + inSISIDXREG(SISSR, 0x2F, temp); + pScrn->videoRam = ((temp & 0x07) + 1) * 256; + inSISIDXREG(SISSR, 0x0C, temp); + if(temp & 0x06) { + pScrn->videoRam *= 2; + pSiS->BusWidth = 64; + } else pSiS->BusWidth = 32; + } else { + inSISIDXREG(SISSR, 0x0C, temp); + config = ((temp & 0x10) >> 2 ) | ((temp & 0x06) >> 1); + pScrn->videoRam = ramsize[config] * 1024; + pSiS->BusWidth = buswidth[config]; + } - SISPTR(pScrn)->MaxClock = 135000; - SISPTR(pScrn)->TurboQueue = FALSE; + if(pSiS->Chipset == PCI_CHIP_SIS530) { - outb(VGA_SEQ_INDEX, RAMSize); - pScrn->videoRam = ramsize[inb(VGA_SEQ_DATA) & 3]; + inSISIDXREG(SISSR, 0x0D, temp); + pSiS->Flags &= ~(UMA); + if(temp & 0x01) { + pSiS->Flags |= UMA; /* Shared fb mode */ + inSISIDXREG(SISSR, 0x10, temp); + pSiS->MemClock = clockTable[temp & 0x03] * 1000; + } else pSiS->MemClock = SiSMclk(pSiS); /* Local fb mode */ + + } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { + + inSISIDXREG(SISSR,0x0e,temp); + + i = temp & 0x03; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DRAM type: %s\n", + dramTypeStr[ramtype[i]]); + + temp = (temp >> 5) & 0x07; + i = SiS6326MCLKIndex[i][temp]; + pSiS->MemClock = SiS6326MCLK[i].mclk; +#if 0 + /* TW: Correct invalid MCLK settings by old BIOSes */ + newsr13 = SiS6326MCLK[i].sr13; + newsr28 = SiS6326MCLK[i].sr28; + newsr29 = SiS6326MCLK[i].sr29; + if((pSiS->ChipRev == 0x92) || + (pSiS->ChipRev == 0xd1) || + (pSiS->ChipRev == 0xd2)) { + if(pSiS->MemClock == 60) { + newsr28 = 0xae; + newsr29 = 0xc4; + } + } +#endif + pSiS->MemClock *= 1000; +#if 0 + inSISIDXREG(SISSR, 0x13, temp); + temp &= 0x80; + temp |= (newsr13 & 0x80); + outSISIDXREG(SISSR,0x13,temp); + outSISIDXREG(SISSR,0x28,newsr28); + outSISIDXREG(SISSR,0x29,newsr29); +#endif + + } else { + + pSiS->MemClock = SiSMclk(pSiS); + + } + + pSiS->Flags &= ~(SYNCDRAM | RAMFLAG); + if(pSiS->oldChipset >= OC_SIS82204) { + inSISIDXREG(SISSR, 0x23, sr23); + inSISIDXREG(SISSR, 0x33, sr33); + inSISIDXREG(SISSR, 0x34, sr34); + if(pSiS->oldChipset >= OC_SIS530A) sr33 &= ~0x08; + if(sr33 & 0x09) { /* 5597: Sync DRAM timing | One cycle EDO ram; */ + pSiS->Flags |= (sr33 & SYNCDRAM); /* 6326: Enable SGRam timing | One cycle EDO ram */ + pSiS->Flags |= RAMFLAG; /* 530: Enable SGRAM timing | reserved (0) */ + } else if((pSiS->oldChipset < OC_SIS530A) && (sr23 & 0x20)) { + pSiS->Flags |= SYNCDRAM; /* 5597, 6326: EDO DRAM enabled */ + } /* 530/620: reserved (0) */ + } + + pSiS->Flags &= ~(ESS137xPRESENT); + if(pSiS->Chipset == PCI_CHIP_SIS530) { + if(pSiS->oldChipset == OC_SIS530A) { + if((systemPCIdevices = xf86GetPciConfigInfo())) { + i = 0; + while((pdptr = systemPCIdevices[i])) { + if((pdptr->pci_vendor == 0x1274) && + ((pdptr->pci_device == 0x5000) || + ((pdptr->pci_device & 0xFFF0) == 0x1370))) { + pSiS->Flags |= ESS137xPRESENT; + break; + } + i++; + } + } + if(pSiS->Flags & ESS137xPRESENT) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS530/620: Found ESS device\n"); + } + } + } + + pSiS->Flags &= ~(SECRETFLAG); + if(pSiS->oldChipset >= OC_SIS5597) { + inSISIDXREG(SISSR, 0x37, sr37); + if(sr37 & 0x80) pSiS->Flags |= SECRETFLAG; + } + + pSiS->Flags &= ~(A6326REVAB); + if(pSiS->Chipset == PCI_CHIP_SIS6326) { + if(((pSiS->ChipRev & 0x0f) == 0x0a) || + ((pSiS->ChipRev & 0x0f) == 0x0b)) { + pSiS->Flags |= A6326REVAB; + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Memory clock: %3.3f MHz\n", + pSiS->MemClock/1000.0); + + if(pSiS->oldChipset > OC_SIS6225) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DRAM bus width: %d bit\n", + pSiS->BusWidth); + } + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "oldChipset = %d, Flags %x\n", pSiS->oldChipset, pSiS->Flags); +#endif } -static void -sis530Setup(ScrnInfoPtr pScrn) +static void +sis300Setup(ScrnInfoPtr pScrn) { - SISPtr pSiS = SISPTR(pScrn); - int ramsize[8] = { 1, 2, 4, 0, 0, 2, 4, 8}; - int buswidth[8] = { 0, 64, 64, 0, 0, 32, 32, 64 }; - int config; - int temp; - - if (pSiS->Chipset == PCI_CHIP_SIS5597) { - pSiS->MaxClock = 135000; - outb(VGA_SEQ_INDEX, FBSize); - pScrn->videoRam = ((inb(VGA_SEQ_DATA) & 7) + 1)*256; - outb(VGA_SEQ_INDEX, Mode64); - if (inb(VGA_SEQ_DATA) & 6) - pScrn->videoRam *= 2; - } - else { - if (pSiS->Chipset == PCI_CHIP_SIS6326) - pSiS->MaxClock = 175000; - if (pSiS->Chipset == PCI_CHIP_SIS530) - pSiS->MaxClock = 230000; - outb(VGA_SEQ_INDEX, RAMSize); - temp = inb(VGA_SEQ_DATA); - config = ((temp & 0x10) >> 2 ) | ((temp & 6) >> 1); - pScrn->videoRam = ramsize[config] * 1024; - pSiS->BusWidth = buswidth[config]; + SISPtr pSiS = SISPTR(pScrn); + const int bus[4] = {32, 64, 128, 32}; + const int adaptermclk[8] = { 66, 83, 100, 133, + 100, 100, 100, 100}; + const int adaptermclk300[8] = { 125, 125, 125, 100, + 100, 100, 100, 100}; + unsigned int config, pciconfig, ramtype; + unsigned char temp; + int cpubuswidth; + int from = X_PROBED; + + pSiS->MemClock = SiSMclk(pSiS); + + inSISIDXREG(SISSR, 0x14, config); + cpubuswidth = bus[config >> 6]; + + inSISIDXREG(SISSR, 0x3A, ramtype); + ramtype &= 0x03; + ramtype += 4; + + switch(pSiS->Chipset) { + case PCI_CHIP_SIS300: + pScrn->videoRam = ((config & 0x3F) + 1) * 1024; + pSiS->BusWidth = cpubuswidth; + break; + case PCI_CHIP_SIS540: + case PCI_CHIP_SIS630: + pciconfig = pciReadByte(0x00000000, 0x63); + if(pciconfig & 0x80) { + pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024; + pSiS->BusWidth = 64; + pciconfig = pciReadByte(0x00000000, 0x64); + if((pciconfig & 0x30) == 0x30) { + pSiS->BusWidth = 128; + pScrn->videoRam <<= 1; + } + ramtype = pciReadByte(0x00000000,0x65); + ramtype &= 0x03; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Shared Memory Area is on DIMM%d\n", ramtype); + ramtype = pciReadByte(0x00000000,(0x60 + ramtype)); + if(ramtype & 0x80) ramtype = 9; + else ramtype = 4; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Shared Memory Area is disabled - awaiting doom\n"); + pScrn->videoRam = ((config & 0x3F) + 1) * 1024; + pSiS->BusWidth = 64; + ramtype = 4; + from = X_INFO; } + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: sis300setup() called with invalid chipset!\n"); + pSiS->BusWidth = 64; + from = X_INFO; + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DRAM type: %s\n", + dramTypeStr[ramtype]); - if (pSiS->Chipset == PCI_CHIP_SIS530) { - outb(VGA_SEQ_INDEX, 0x10); - pSiS->MemClock = clockTable[inb(VGA_SEQ_DATA) & 0x03] * 1000; - outb(VGA_SEQ_INDEX, 0x0d); - if (inb(VGA_SEQ_DATA) & 0x01) - pSiS->Flags |= UMA; - } else - pSiS->MemClock = SiSMclk(pSiS); - - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected memory clock : %3.3fMHz\n", - pSiS->MemClock/1000.0); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Memory clock: %3.3f MHz\n", + pSiS->MemClock/1000.0); + + if(pSiS->Chipset == PCI_CHIP_SIS300) { + if(pSiS->ChipRev > 0x13) { + inSISIDXREG(SISSR, 0x3A, temp); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "(Adapter assumes MCLK being %d Mhz)\n", + adaptermclk300[(temp & 0x07)]); + } + } else { + inSISIDXREG(SISSR, 0x1A, temp); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "(Adapter assumes MCLK being %d Mhz)\n", + adaptermclk[(temp & 0x07)]); + } + + xf86DrvMsg(pScrn->scrnIndex, from, + "DRAM bus width: %d bit\n", + pSiS->BusWidth); } -static void -sis300Setup(ScrnInfoPtr pScrn) +/* For 315, 315H, 315PRO, 330 */ +static void +sis315Setup(ScrnInfoPtr pScrn) { - SISPtr pSiS = SISPTR(pScrn); - int bus[4] = {32, 64, 128, 32}; - unsigned int config; - - pSiS->MemClock = SiSMclk(pSiS); - - outb(VGA_SEQ_INDEX, 0x14); - config = inb(VGA_SEQ_DATA); - pScrn->videoRam = ((config & 0x3F) + 1) * 1024; - pSiS->BusWidth =bus[config >> 6]; - pSiS->MaxClock = sis300MemBandWidth(pScrn); - - outb(VGA_SEQ_INDEX, 0x3A); - config = inb(VGA_SEQ_DATA) & 3; - - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected DRAM type : %s\n", dramTypeStr[config+4]); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected memory clock : %3.3fMHz\n", - pSiS->MemClock/1000.0); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected VRAM bus width is %d\n", pSiS->BusWidth); - inSISIDXREG(0x3D4, 0x32, config); - if (config & 0x5F) - pSiS->VBFlags = 1; + SISPtr pSiS = SISPTR(pScrn); + int busSDR[4] = {64, 64, 128, 128}; + int busDDR[4] = {32, 32, 64, 64}; + int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2}; + unsigned int config, config1, config2; + char *dramTypeStr315[] = { + "Single Channel 1 rank SDR SDRAM", + "Single Channel 1 rank SDR SGRAM", + "Single Channel 1 rank DDR SDRAM", + "Single Channel 1 rank DDR SGRAM", + "Single Channel 2 rank SDR SDRAM", + "Single Channel 2 rank SDR SGRAM", + "Single Channel 2 rank DDR SDRAM", + "Single Channel 2 rank DDR SGRAM", + "Asymmetric SDR SDRAM", + "Asymmetric SDR SGRAM", + "Asymmetric DDR SDRAM", + "Asymmetric DDR SGRAM", + "Dual channel SDR SDRAM", + "Dual channel SDR SGRAM", + "Dual channel DDR SDRAM", + "Dual channel DDR SGRAM"}; + char *dramTypeStr330[] = { + "Single Channel SDR SDRAM", + "", + "Single Channel DDR SDRAM", + "", + "--unknown--", + "", + "--unknown--", + "", + "Asymetric Dual Channel SDR SDRAM", + "", + "Asymetric Dual Channel DDR SDRAM", + "", + "Dual channel SDR SDRAM", + "", + "Dual channel DDR SDRAM", + ""}; + + inSISIDXREG(SISSR, 0x14, config); + config1 = (config & 0x0C) >> 2; + inSISIDXREG(SISSR, 0x3A, config2); + config2 &= 0x03; + + pScrn->videoRam = (1 << ((config & 0xF0) >> 4)) * 1024; + + if(pSiS->Chipset == PCI_CHIP_SIS330) { + + if(config1) pScrn->videoRam <<= 1; + + } else { + + /* If SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK -> mem * 2 */ + if((config1 == 0x01) || (config1 == 0x03)) + pScrn->videoRam <<= 1; + + /* If DDR asymetric -> mem * 1,5 */ + if(config1 == 0x02) + pScrn->videoRam += pScrn->videoRam/2; + + } + + pSiS->MemClock = SiSMclk(pSiS); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DRAM type: %s\n", + (pSiS->Chipset == PCI_CHIP_SIS330) ? + dramTypeStr330[(config1 * 4) + (config2 & 0x02)] : + dramTypeStr315[(config1 * 4) + config2]); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Memory clock: %3.3f MHz\n", + pSiS->MemClock/1000.0); + + /* TW: DDR -> mclk * 2 - needed for bandwidth calculation */ + if(pSiS->Chipset == PCI_CHIP_SIS330) { + if(config2 & 0x02) { + pSiS->MemClock *= 2; + if(config1 == 0x02) { + pSiS->BusWidth = busDDRA[0]; + } else { + pSiS->BusWidth = busDDR[(config & 0x02)]; + } + } else { + if(config1 == 0x02) { + pSiS->BusWidth = busDDRA[2]; + } else { + pSiS->BusWidth = busSDR[(config & 0x02)]; + } + } + } else { + if(config2 & 0x02) pSiS->MemClock *= 2; + if(config1 == 0x02) + pSiS->BusWidth = busDDRA[(config & 0x03)]; + else if(config2 & 0x02) + pSiS->BusWidth = busDDR[(config & 0x03)]; + else + pSiS->BusWidth = busSDR[(config & 0x03)]; + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DRAM bus width: %d bit\n", + pSiS->BusWidth); +} + +/* TW: for 550, 650, 740, 660 */ +static void +sis550Setup(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned int config, ramtype=0, i; + CARD8 pciconfig, temp; + BOOLEAN alldone = FALSE; + + pSiS->MemClock = SiSMclk(pSiS); + + if(pSiS->Chipset == PCI_CHIP_SIS660) { + + /* TODO - this is entirely guessed */ + + pciconfig = pciReadByte(0x00000000, 0x64); + if(pciconfig & 0x80) { + pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 22)) / 1024; + pSiS->BusWidth = 64; + for(i=0; i<=3; i++) { + if(pciconfig & (1 << i)) { + temp = pciReadByte(0x00000000, 0x60 + i); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DIMM%d is %s SDRAM\n", + i, (temp & 0x40) ? "DDR" : "SDR"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DIMM%d is not installed\n", i); + } + } + pciconfig = pciReadByte(0x00000000, 0x7c); + if(pciconfig & 0x02) ramtype = 8; + else ramtype = 4; + alldone = TRUE; + } + + } else if(pSiS->Chipset == PCI_CHIP_SIS650) { + + pciconfig = pciReadByte(0x00000000, 0x64); + if(pciconfig & 0x80) { + pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 22)) / 1024; + pSiS->BusWidth = 64; + for(i=0; i<=3; i++) { + if(pciconfig & (1 << i)) { + temp = pciReadByte(0x00000000, 0x60 + i); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DIMM%d is %s SDRAM\n", + i, (temp & 0x40) ? "DDR" : "SDR"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DIMM%d is not installed\n", i); + } + } + pciconfig = pciReadByte(0x00000000, 0x7c); + if(pciconfig & 0x02) ramtype = 8; + else ramtype = 4; + alldone = TRUE; + } + + } else { + + pciconfig = pciReadByte(0x00000000, 0x63); + if(pciconfig & 0x80) { + pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024; + pSiS->BusWidth = 64; + ramtype = pciReadByte(0x00000000,0x65); + ramtype &= 0x01; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Shared Memory Area is on DIMM%d\n", ramtype); + ramtype = 4; + alldone = TRUE; + } + + } + + if(!alldone) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Shared Memory Area is disabled - awaiting doom\n"); + inSISIDXREG(SISSR, 0x14, config); + pScrn->videoRam = (((config & 0x3F) + 1) * 4) * 1024; + if(pSiS->Chipset == PCI_CHIP_SIS650) { + ramtype = (((config & 0x80) >> 7) << 2) + 4; + pSiS->BusWidth = 64; /* (config & 0x40) ? 128 : 64; */ + } else { + ramtype = 4; + pSiS->BusWidth = 64; + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DRAM type: %s\n", + dramTypeStr[ramtype]); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Memory clock: %3.3f MHz\n", + pSiS->MemClock/1000.0); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DRAM bus width: %d bit\n", + pSiS->BusWidth); + + /* TW: DDR -> Mclk * 2 - needed for bandwidth calculation */ + if(ramtype == 8) pSiS->MemClock *= 2; } void SiSSetup(ScrnInfoPtr pScrn) { - SISPTR(pScrn)->Flags = 0; - - SISPTR(pScrn)->VBFlags = 0; - switch (SISPTR(pScrn)->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - sis530Setup(pScrn); - break; - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - sis300Setup(pScrn); - break; - default: - sisOldChipSetup(pScrn); - break; - } + SISPtr pSiS = SISPTR(pScrn); + + pSiS->Flags = 0; + pSiS->VBFlags = 0; + + switch (SISPTR(pScrn)->Chipset) { + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS630: /* +730 */ + case PCI_CHIP_SIS540: + sis300Setup(pScrn); + break; + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + sis315Setup(pScrn); + break; + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: /* + 740 */ + case PCI_CHIP_SIS660: /* + 760 */ + sis550Setup(pScrn); + break; + case PCI_CHIP_SIS5597: + case PCI_CHIP_SIS6326: + case PCI_CHIP_SIS530: + default: + sisOldSetup(pScrn); + break; + } } + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.c index de5bda5ae..0e206b786 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.c @@ -1,8 +1,29 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.c,v 1.7 2003/05/21 15:15:04 twini Exp $ */ /* - * Copyright (c) 1999, The XFree86 Project Inc. - * based on code written by Mark Vojkovich <markv@valinux.com> + * Copyright (c) 1999, The XFree86 Project Inc. + * based on code written by Mark Vojkovich <markv@valinux.com> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * TW: This module doesn't use CurrentLayout, because it is never + * active when DGA is active and vice versa. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.c,v 1.2 2001/04/19 14:11:37 alanh Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.h index b44922131..1c670e903 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.h @@ -1,5 +1,25 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.h,v 1.2 2001/04/19 14:11:37 alanh Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.h,v 1.5 2003/05/21 15:15:04 twini Exp $ */ +/* + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + void SISPointerMoved(int index, int x, int y); void SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); void SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c index d8ed1144c..694a1eb44 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c @@ -1,29 +1,29 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c,v 1.10 2003/01/29 15:42:17 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c,v 1.15 2003/06/26 22:35:19 twini Exp $ */ /* - * Video bridge detection and configuration for 300 and 310/325 series + * Video bridge detection and configuration for 300, 315 and 330 series * - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Thomas Winischhofer not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Winischhofer makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THOMAS WINISCHHOFER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Thomas Winischhofer <thomas@winischhofer.net> - * (Completely rewritten) + * */ #include "xf86.h" @@ -37,64 +37,49 @@ static const SiS_LCD_StStruct SiS300_LCD_Type[]= { - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 0 - invalid */ - { VB_LCD_800x600, 800, 600, LCD_800x600, 0}, /* 1 */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 2 */ - { VB_LCD_1280x1024,1280, 1024, LCD_1280x1024, 2}, /* 3 */ - { VB_LCD_1280x960, 1280, 960, LCD_1280x960, 3}, /* 4 */ - { VB_LCD_640x480, 640, 480, LCD_640x480, 4}, /* 5 */ - { VB_LCD_1024x600, 1024, 600, LCD_1024x600, 10}, /* 6 */ - { VB_LCD_1152x768, 1152, 768, LCD_1152x768, 7}, /* 7 */ - { VB_LCD_320x480, 320, 480, LCD_320x480, 6}, /* 8 */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 9 */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* a */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* b */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* c */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* d */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* e */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* f */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* 0 - invalid */ + { VB_LCD_800x600, 800, 600, LCD_800x600 }, /* 1 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* 2 */ + { VB_LCD_1280x1024,1280, 1024, LCD_1280x1024}, /* 3 */ + { VB_LCD_1280x960, 1280, 960, LCD_1280x960 }, /* 4 */ + { VB_LCD_640x480, 640, 480, LCD_640x480 }, /* 5 */ + { VB_LCD_1024x600, 1024, 600, LCD_1024x600 }, /* 6 */ + { VB_LCD_1152x768, 1152, 768, LCD_1152x768 }, /* 7 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* 8 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* 9 */ + { VB_LCD_1280x768, 1280, 768, LCD_1280x768 }, /* a */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* b */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* c */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* d */ + { VB_LCD_320x480, 320, 480, LCD_320x480 }, /* e */ + { VB_LCD_CUSTOM, 0, 0, LCD_CUSTOM } /* f */ }; -static const SiS_LCD_StStruct SiS310_LCD_Type[]= +static const SiS_LCD_StStruct SiS315_LCD_Type[]= { - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 0 - invalid */ - { VB_LCD_800x600, 800, 600, LCD_800x600, 0}, /* 1 */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 2 */ - { VB_LCD_1280x1024, 1280,1024, LCD_1280x1024, 2}, /* 3 */ - { VB_LCD_640x480, 640, 480, LCD_640x480, 4}, /* 4 */ - { VB_LCD_1024x600, 1024, 600, LCD_1024x600, 10}, /* 5 */ - { VB_LCD_1152x864, 1152, 864, LCD_1152x864, 11}, /* 6 */ - { VB_LCD_1280x960, 1280, 960, LCD_1280x960, 3}, /* 7 */ - { VB_LCD_1152x768, 1152, 768, LCD_1152x768, 7}, /* 8 */ - { VB_LCD_1400x1050, 1400,1050, LCD_1400x1050, 8}, /* 9 */ - { VB_LCD_1280x768, 1280, 768, LCD_1280x768, 9}, /* a */ - { VB_LCD_1600x1200, 1600,1200, LCD_1600x1200, 5}, /* b */ - { VB_LCD_320x480, 320, 480, LCD_320x480, 6}, /* c */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* d */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* e */ - { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1} /* f */ -}; - -static const char *panelres[] = { - "800x600", - "1024x768", - "1280x1024", - "1280x960", - "640x480", - "1600x1200", - "320x480", - "1152x768", - "1400x1050", - "1280x768", - "1024x600", - "1152x864" + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* 0 - invalid */ + { VB_LCD_800x600, 800, 600, LCD_800x600 }, /* 1 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768 }, /* 2 */ + { VB_LCD_1280x1024,1280, 1024, LCD_1280x1024 }, /* 3 */ + { VB_LCD_640x480, 640, 480, LCD_640x480 }, /* 4 */ + { VB_LCD_1024x600, 1024, 600, LCD_1024x600 }, /* 5 */ + { VB_LCD_1152x864, 1152, 864, LCD_1152x864 }, /* 6 */ + { VB_LCD_1280x960, 1280, 960, LCD_1280x960 }, /* 7 */ + { VB_LCD_1152x768, 1152, 768, LCD_1152x768 }, /* 8 */ + { VB_LCD_1400x1050,1400, 1050, LCD_1400x1050 }, /* 9 */ + { VB_LCD_1280x768, 1280, 768, LCD_1280x768 }, /* a */ + { VB_LCD_1600x1200,1600, 1200, LCD_1600x1200 }, /* b */ + { VB_LCD_640x480_2, 640, 480, LCD_640x480_2 }, /* c DSTN/FSTN */ + { VB_LCD_640x480_3, 640, 480, LCD_640x480_3 }, /* d DSTN/FSTN */ + { VB_LCD_320x480, 320, 480, LCD_320x480 }, /* e */ + { VB_LCD_CUSTOM, 0, 0, LCD_CUSTOM, } /* f */ }; /* Detect CRT1 */ void SISCRT1PreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - unsigned char CR32, SR17; + unsigned char CR32; unsigned char CRT1Detected = 0; unsigned char OtherDevices = 0; @@ -111,36 +96,24 @@ void SISCRT1PreInit(ScrnInfoPtr pScrn) #endif inSISIDXREG(SISCR, 0x32, CR32); - inSISIDXREG(SISSR, 0x17, SR17); - - if ( (pSiS->VGAEngine == SIS_300_VGA) && - (pSiS->Chipset != PCI_CHIP_SIS300) && - (SR17 & 0x0F) ) { - - if(SR17 & 0x01) CRT1Detected = 1; - if(SR17 & 0x0E) OtherDevices = 1; - } else { - - if(CR32 & 0x20) CRT1Detected = 1; - if(CR32 & 0x5F) OtherDevices = 1; - - } + if(CR32 & 0x20) CRT1Detected = 1; + if(CR32 & 0x5F) OtherDevices = 1; if(pSiS->CRT1off == -1) { - if(!CRT1Detected) { + if(!CRT1Detected) { - /* BIOS detected no CRT1. */ - /* If other devices exist, switch it off */ - if(OtherDevices) pSiS->CRT1off = 1; - else pSiS->CRT1off = 0; + /* BIOS detected no CRT1. */ + /* If other devices exist, switch it off */ + if(OtherDevices) pSiS->CRT1off = 1; + else pSiS->CRT1off = 0; - } else { + } else { - /* BIOS detected CRT1, leave/switch it on */ - pSiS->CRT1off = 0; + /* BIOS detected CRT1, leave/switch it on */ + pSiS->CRT1off = 0; - } + } } xf86DrvMsg(pScrn->scrnIndex, X_PROBED, @@ -152,62 +125,132 @@ void SISCRT1PreInit(ScrnInfoPtr pScrn) void SISLCDPreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - unsigned char CR32, SR17, CR36, CR37; - USHORT textindex; + unsigned char CR32, CR36, CR37; if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) { return; } inSISIDXREG(SISCR, 0x32, CR32); - inSISIDXREG(SISSR, 0x17, SR17); - - if( (pSiS->VGAEngine == SIS_300_VGA) && - (pSiS->Chipset != PCI_CHIP_SIS300) && - (SR17 & 0x0F) ) { - if(SR17 & 0x02) - pSiS->VBFlags |= CRT2_LCD; - } else { - if(CR32 & 0x08) - pSiS->VBFlags |= CRT2_LCD; + + if(CR32 & 0x08) pSiS->VBFlags |= CRT2_LCD; + + /* TW: If no panel has been detected by the BIOS during booting, + * we try to detect it ourselves at this point. This is useful + * on machines with DVI connectors where the panel was + * connected after booting. This is only supported on the + * 315/330 series and the 301/30xB bridge (because the 30xLV/LVX + * don't seem to have a DDC port and operates only LVDS panels + * which mostly don't support DDC). We only do this if there was no + * secondary VGA detected by the BIOS, because LCD and VGA2 + * share the same DDC channel and might be misdetected as the + * wrong type (especially if the LCD panel only supports + * EDID Version 1). + */ +#ifdef SISDUALHEAD + if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) { +#endif + if((pSiS->VGAEngine == SIS_315_VGA) && + (pSiS->VBFlags & (VB_301|VB_301B|VB_302B)) && + (!(pSiS->VBFlags & VB_30xBDH))) { + + if(pSiS->forcecrt2redetection) { + pSiS->VBFlags &= ~CRT2_LCD; + } + + if(!(pSiS->nocrt2ddcdetection)) { + if((!(pSiS->VBFlags & CRT2_LCD)) && (!(CR32 & 0x10))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s LCD/Plasma panel, sensing via DDC\n", + pSiS->forcecrt2redetection ? + "Forced re-detection of" : "BIOS detected no"); + if(SiS_SenseLCDDDC(pSiS->SiS_Pr, pSiS)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "DDC error during LCD panel detection\n"); + } else { + inSISIDXREG(SISCR, 0x32, CR32); + if(CR32 & 0x08) { + pSiS->VBFlags |= CRT2_LCD; + pSiS->postVBCR32 |= 0x08; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "No LCD/Plasma panel detected\n"); + } + } + } + } + + } +#ifdef SISDUALHEAD } +#endif if(pSiS->VBFlags & CRT2_LCD) { - inSISIDXREG(SISCR, 0x36, CR36); - inSISIDXREG(SISCR, 0x37, CR37); - if((pSiS->VGAEngine == SIS_315_VGA) && (!CR36)) { - /* TW: Old 650/301LV BIOS version "forgot" to set CR36, CR37 */ - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "BIOS-provided LCD information invalid, probing myself...\n"); - if(pSiS->VBFlags & VB_LVDS) pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 1; - else pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 0; - SiS_GetPanelID(pSiS->SiS_Pr, &pSiS->sishw_ext); - inSISIDXREG(SISCR, 0x36, CR36); - inSISIDXREG(SISCR, 0x37, CR37); - } - if(pSiS->VGAEngine == SIS_300_VGA) { - pSiS->VBLCDFlags |= SiS300_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag; - pSiS->LCDheight = SiS300_LCD_Type[(CR36 & 0x0f)].LCDheight; - pSiS->LCDwidth = SiS300_LCD_Type[(CR36 & 0x0f)].LCDwidth; - pSiS->sishw_ext.ulCRT2LCDType = SiS300_LCD_Type[(CR36 & 0x0f)].LCDtype; - textindex = SiS300_LCD_Type[(CR36 & 0x0f)].LCDrestextindex; - } else { - pSiS->VBLCDFlags |= SiS310_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag; - pSiS->LCDheight = SiS310_LCD_Type[(CR36 & 0x0f)].LCDheight; - pSiS->LCDwidth = SiS310_LCD_Type[(CR36 & 0x0f)].LCDwidth; - pSiS->sishw_ext.ulCRT2LCDType = SiS310_LCD_Type[(CR36 & 0x0f)].LCDtype; - textindex = SiS310_LCD_Type[(CR36 & 0x0f)].LCDrestextindex; - } - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected LCD panel resolution %s (type %d, %s%s)\n", - panelres[textindex], + inSISIDXREG(SISCR, 0x36, CR36); + inSISIDXREG(SISCR, 0x37, CR37); + if(pSiS->SiS_Pr->SiS_CustomT == CUT_BARCO1366) { + pSiS->VBLCDFlags |= VB_LCD_BARCO1366; + pSiS->LCDwidth = 1360; + pSiS->LCDheight = 1024; + if(CR37 & 0x10) pSiS->VBLCDFlags |= VB_LCD_EXPANDING; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected LCD panel (%dx%d, type %d, %sexpanding, RGB%d)\n", + pSiS->LCDwidth, pSiS->LCDheight, + ((CR36 & 0xf0) >> 4), + (CR37 & 0x10) ? "" : "non-", + (CR37 & 0x01) ? 18 : 24); + } else if(pSiS->SiS_Pr->SiS_CustomT == CUT_PANEL848) { + pSiS->VBLCDFlags |= VB_LCD_848x480; + pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = 848; + pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = 480; + pSiS->VBLCDFlags |= VB_LCD_EXPANDING; + pSiS->sishw_ext.ulCRT2LCDType = LCD_848x480; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Assuming LCD/plasma panel (848x480, expanding, RGB24)\n"); + } else { + if((pSiS->VGAEngine == SIS_315_VGA) && (!CR36)) { + /* TW: Old 650/301LV BIOS version "forgot" to set CR36, CR37 */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "BIOS-provided LCD information invalid, probing myself...\n"); + if(pSiS->VBFlags & VB_LVDS) pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 1; + else pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 0; + SiS_GetPanelID(pSiS->SiS_Pr, &pSiS->sishw_ext); + inSISIDXREG(SISCR, 0x36, CR36); + inSISIDXREG(SISCR, 0x37, CR37); + } + if(((CR36 & 0x0f) == 0x0f) && (pSiS->SiS_Pr->CP_HaveCustomData)) { + pSiS->VBLCDFlags |= VB_LCD_CUSTOM; + pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY; + pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX; + pSiS->sishw_ext.ulCRT2LCDType = LCD_CUSTOM; + if(CR37 & 0x10) pSiS->VBLCDFlags |= VB_LCD_EXPANDING; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected non-standard LCD/Plasma panel (max. X %d Y %d, preferred %dx%d, RGB%d)\n", + pSiS->SiS_Pr->CP_MaxX, pSiS->SiS_Pr->CP_MaxY, + pSiS->SiS_Pr->CP_PreferredX, pSiS->SiS_Pr->CP_PreferredY, + (CR37 & 0x01) ? 18 : 24); + } else { + if(pSiS->VGAEngine == SIS_300_VGA) { + pSiS->VBLCDFlags |= SiS300_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag; + pSiS->LCDheight = SiS300_LCD_Type[(CR36 & 0x0f)].LCDheight; + pSiS->LCDwidth = SiS300_LCD_Type[(CR36 & 0x0f)].LCDwidth; + pSiS->sishw_ext.ulCRT2LCDType = SiS300_LCD_Type[(CR36 & 0x0f)].LCDtype; + if(CR37 & 0x10) pSiS->VBLCDFlags |= VB_LCD_EXPANDING; + } else { + pSiS->VBLCDFlags |= SiS315_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag; + pSiS->LCDheight = SiS315_LCD_Type[(CR36 & 0x0f)].LCDheight; + pSiS->LCDwidth = SiS315_LCD_Type[(CR36 & 0x0f)].LCDwidth; + pSiS->sishw_ext.ulCRT2LCDType = SiS315_LCD_Type[(CR36 & 0x0f)].LCDtype; + if(CR37 & 0x10) pSiS->VBLCDFlags |= VB_LCD_EXPANDING; + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected LCD/Plasma panel (%dx%d, type %d, %sexpanding, RGB%d)\n", + pSiS->LCDwidth, pSiS->LCDheight, (pSiS->VGAEngine == SIS_315_VGA) ? ((CR36 & 0x0f) - 1) : ((CR36 & 0xf0) >> 4), - (pSiS->VBFlags & VB_LVDS) ? - (CR37 & 0x10 ? "non-expanding, " : "expanding, ") : - ( ((pSiS->VBFlags & VB_301B) && (pSiS->VGAEngine == SIS_300_VGA)) ? - (CR37 & 0x10 ? "non-expanding, " : "expanding, ") : - (CR37 & 0x10 ? "self-scaling, " : "non-self-scaling, ") ), - CR37 & 0x01 ? "RGB18" : "RGB24"); + (CR37 & 0x10) ? "" : "non-", + (CR37 & 0x01) ? 18 : 24); + } + } } } @@ -215,19 +258,18 @@ void SISLCDPreInit(ScrnInfoPtr pScrn) void SISTVPreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - unsigned char SR16, SR17, SR38, CR32, CR38=0, CR79; + unsigned char SR16, SR38, CR32, CR38=0, CR79; int temp = 0; if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return; inSISIDXREG(SISCR, 0x32, CR32); - inSISIDXREG(SISSR, 0x17, SR17); inSISIDXREG(SISSR, 0x16, SR16); inSISIDXREG(SISSR, 0x38, SR38); switch(pSiS->VGAEngine) { case SIS_300_VGA: - if(pSiS->Chipset != PCI_CHIP_SIS300) temp = 0x35; + if(pSiS->Chipset == PCI_CHIP_SIS630) temp = 0x35; break; case SIS_315_VGA: temp = 0x38; @@ -238,76 +280,67 @@ void SISTVPreInit(ScrnInfoPtr pScrn) } #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(vb.c: SR17=%02x CR32=%02x)\n", SR17, CR32); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(vb.c: SR16=%02x SR38=%02x)\n", SR16, SR38); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "(vb.c: CR32=%02x SR16=%02x SR38=%02x)\n", + CR32, SR16, SR38); #endif - if( (pSiS->VGAEngine == SIS_300_VGA) && - (pSiS->Chipset != PCI_CHIP_SIS300) && - (SR17 & 0x0F) ) { - - if(SR17 & 0x04) - pSiS->VBFlags |= CRT2_TV; - - if(SR17 & 0x20) - pSiS->VBFlags |= TV_SVIDEO; - else if (SR17 & 0x10) - pSiS->VBFlags |= TV_AVIDEO; - - if(pSiS->VBFlags & (TV_SVIDEO | TV_AVIDEO)) { - if(SR16 & 0x20) - pSiS->VBFlags |= TV_PAL; - else - pSiS->VBFlags |= TV_NTSC; - } - - } else { - - if(CR32 & 0x47) - pSiS->VBFlags |= CRT2_TV; - - if(CR32 & 0x04) - pSiS->VBFlags |= TV_SCART; - else if(CR32 & 0x02) - pSiS->VBFlags |= TV_SVIDEO; - else if(CR32 & 0x01) - pSiS->VBFlags |= TV_AVIDEO; - else if(CR32 & 0x40) - pSiS->VBFlags |= (TV_SVIDEO | TV_HIVISION); - else if((CR38 & 0x04) && (pSiS->VBFlags & VB_CHRONTEL)) - pSiS->VBFlags |= (TV_CHSCART | TV_PAL); - else if((CR38 & 0x08) && (pSiS->VBFlags & VB_CHRONTEL)) - pSiS->VBFlags |= (TV_CHHDTV | TV_NTSC); + if(CR32 & 0x47) + pSiS->VBFlags |= CRT2_TV; + + if(CR32 & 0x04) + pSiS->VBFlags |= TV_SCART; + else if(CR32 & 0x02) + pSiS->VBFlags |= TV_SVIDEO; + else if(CR32 & 0x01) + pSiS->VBFlags |= TV_AVIDEO; + else if(CR32 & 0x40) + pSiS->VBFlags |= (TV_SVIDEO | TV_HIVISION); + else if((CR38 & 0x04) && (pSiS->VBFlags & (VB_301LV | VB_302LV))) + pSiS->VBFlags |= TV_HIVISION_LV; + else if((CR38 & 0x04) && (pSiS->VBFlags & VB_CHRONTEL)) + pSiS->VBFlags |= (TV_CHSCART | TV_PAL); + else if((CR38 & 0x08) && (pSiS->VBFlags & VB_CHRONTEL)) + pSiS->VBFlags |= (TV_CHHDTV | TV_NTSC); - if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION)) { - if( (pSiS->Chipset == PCI_CHIP_SIS550) || /* TW: ? */ - (pSiS->Chipset == PCI_CHIP_SIS650) ) { - inSISIDXREG(SISCR, 0x79, CR79); - if(CR79 & 0x20) { - pSiS->VBFlags |= TV_PAL; - if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM; - else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN; - } else - pSiS->VBFlags |= TV_NTSC; - } else if(pSiS->VGAEngine == SIS_300_VGA) { - /* TW: Should be SR38 here as well, but this - * does not work. Looks like a BIOS bug (2.04.5c). - */ - if(SR16 & 0x20) - pSiS->VBFlags |= TV_PAL; - else - pSiS->VBFlags |= TV_NTSC; - } else { /* 315, 330 */ - if(SR38 & 0x01) { - pSiS->VBFlags |= TV_PAL; - if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM; - else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN; - } else - pSiS->VBFlags |= TV_NTSC; - } - } + if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION | TV_HIVISION_LV)) { + if(pSiS->VGAEngine == SIS_300_VGA) { + /* TW: Should be SR38, but this does not work. */ + if(SR16 & 0x20) + pSiS->VBFlags |= TV_PAL; + else + pSiS->VBFlags |= TV_NTSC; + } else if(pSiS->Chipset == PCI_CHIP_SIS550) { + inSISIDXREG(SISCR, 0x7a, CR79); + if(CR79 & 0x08) { + inSISIDXREG(SISCR, 0x79, CR79); + CR79 >>= 5; + } + if(CR79 & 0x01) { + pSiS->VBFlags |= TV_PAL; + if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM; + else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN; + } else + pSiS->VBFlags |= TV_NTSC; + } else if((pSiS->Chipset == PCI_CHIP_SIS650) || (pSiS->Chipset == PCI_CHIP_SIS660)) { + inSISIDXREG(SISCR, 0x79, CR79); + if(CR79 & 0x20) { + pSiS->VBFlags |= TV_PAL; + if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM; + else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN; + } else + pSiS->VBFlags |= TV_NTSC; + } else { /* 315, 330 */ + if(SR38 & 0x01) { + pSiS->VBFlags |= TV_PAL; + if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM; + else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN; + } else + pSiS->VBFlags |= TV_NTSC; + } } - if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION | TV_CHSCART | TV_CHHDTV)) { + + if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION | TV_HIVISION_LV | TV_CHSCART | TV_CHHDTV)) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%sTV standard %s\n", (pSiS->VBFlags & (TV_CHSCART | TV_CHHDTV)) ? "Using " : "Detected default ", @@ -322,30 +355,60 @@ void SISTVPreInit(ScrnInfoPtr pScrn) void SISCRT2PreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - unsigned char SR17, CR32; + unsigned char CR32; - if (!(pSiS->VBFlags & VB_VIDEOBRIDGE)) + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return; - /* CRT2-VGA not supported on LVDS and 30xLV(X) */ - if (pSiS->VBFlags & (VB_LVDS|VB_30xLV|VB_30xLVX)) + /* CRT2-VGA not supported on LVDS and 30xLV */ + if(pSiS->VBFlags & (VB_LVDS|VB_301LV|VB_302LV)) return; inSISIDXREG(SISCR, 0x32, CR32); - inSISIDXREG(SISSR, 0x17, SR17); + + if(CR32 & 0x10) pSiS->VBFlags |= CRT2_VGA; - if( (pSiS->VGAEngine == SIS_300_VGA) && - (pSiS->Chipset != PCI_CHIP_SIS300) && - (SR17 & 0x0F) ) { - - if(SR17 & 0x08) - pSiS->VBFlags |= CRT2_VGA; +#ifdef SISDUALHEAD + if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) { +#endif - } else { + if(pSiS->forcecrt2redetection) { + pSiS->VBFlags &= ~CRT2_VGA; + } + + /* We don't trust the normal sensing method for VGA2 since + * it is performed by the BIOS during POST, and it is + * impossible to sense VGA2 if the bridge is disabled. + * Therefore, we try sensing VGA2 by DDC as well (if not + * detected otherwise and only if there is no LCD panel + * which is prone to be misdetected as a secondary VGA) + */ + if(!(pSiS->nocrt2ddcdetection)) { + if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B)) { + if(!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s secondary VGA, sensing via DDC\n", + pSiS->forcecrt2redetection ? + "Forced redetection of" : "BIOS detected no"); + if(SiS_SenseVGA2DDC(pSiS->SiS_Pr, pSiS)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "DDC error during secondary VGA detection\n"); + } else { + inSISIDXREG(SISCR, 0x32, CR32); + if(CR32 & 0x10) { + pSiS->VBFlags |= CRT2_VGA; + pSiS->postVBCR32 |= 0x10; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected secondary VGA connection\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "No secondary VGA connection detected\n"); + } + } + } + } + } - if(CR32 & 0x10) - pSiS->VBFlags |= CRT2_VGA; - } } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h index 4419ccf39..bd9bc429d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h @@ -1,29 +1,29 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h,v 1.7 2003/01/29 15:42:17 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h,v 1.10 2003/05/21 15:15:04 twini Exp $ */ /* - * Video bridge detection and configuration for 300 and 310/325 series + * Video bridge detection and configuration for 300, 315 and 330 series + * Data and prototypes * - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Thomas Winischhofer not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Winischhofer makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THOMAS WINISCHHOFER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Thomas Winischhofer <thomas@winischhofer.net> - * (Completely rewritten) */ typedef struct _SiS_LCD_StStruct @@ -32,7 +32,6 @@ typedef struct _SiS_LCD_StStruct USHORT LCDwidth; USHORT LCDheight; USHORT LCDtype; - UCHAR LCDrestextindex; } SiS_LCD_StStruct; void SISCRT1PreInit(ScrnInfoPtr pScrn); @@ -41,3 +40,5 @@ void SISTVPreInit(ScrnInfoPtr pScrn); void SISCRT2PreInit(ScrnInfoPtr pScrn); extern BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS); +extern USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c index 5d4553130..ff2e1852a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c @@ -1,31 +1,31 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c,v 1.24 2003/08/07 12:52:23 twini Exp $ */ /* - * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Mode setup and basic video bridge detection + * + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. + * + * Init() function for old series (except for FIFO calculation) based on code + * which was Copyright 1998,1999 by Alan Hourihane, Wigan, England. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Alan Hourihane not be used in + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c,v 1.2 2000/02/18 12:20:01 tsi Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -34,798 +34,1719 @@ #include "xf86PciInfo.h" #include "xf86Pci.h" -#include "vgaHW.h" - #include "sis.h" #include "sis_regs.h" -#include "sis_bios.h" - +#include "sis_dac.h" -#define Midx 0 -#define Nidx 1 -#define VLDidx 2 -#define Pidx 3 -#define PSNidx 4 -#define Fref 14318180 -/* stability constraints for internal VCO -- MAX_VCO also determines - * the maximum Video pixel clock */ -#define MIN_VCO Fref -#define MAX_VCO 135000000 -#define MAX_VCO_5597 353000000 -#define MAX_PSN 0 /* no pre scaler for this chip */ -#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */ +#if 0 +#define TV6326TEST +#endif +static Bool SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static Bool SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode); +/* To be used internally only */ +int SISDoSense(ScrnInfoPtr pScrn, int tempbl, int tempbh, int tempcl, int tempch); +void SISSense30x(ScrnInfoPtr pScrn); +int SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl); +void SISSense6326(ScrnInfoPtr pScrn); +static void SiS6326TVDelay(ScrnInfoPtr pScrn, int delay); + +const CARD8 SiS6326TVRegs1[14] = { + 0x00,0x01,0x02,0x03,0x04,0x11,0x12,0x13,0x21,0x26,0x27,0x3a,0x3c,0x43 +}; +const CARD8 SiS6326TVRegs1_NTSC[6][14] = { + {0x81,0x3f,0x49,0x1b,0xa9,0x03,0x00,0x09,0x08,0x7d,0x00,0x88,0x30,0x60}, + {0x81,0x3f,0x49,0x1d,0xa0,0x03,0x00,0x09,0x08,0x7d,0x00,0x88,0x30,0x60}, + {0x81,0x45,0x24,0x8e,0x26,0x0b,0x00,0x09,0x02,0xfe,0x00,0x09,0x51,0x60}, + {0x81,0x45,0x24,0x8e,0x26,0x07,0x00,0x29,0x04,0x30,0x10,0x3b,0x61,0x60}, + {0x81,0x3f,0x24,0x8e,0x26,0x09,0x00,0x09,0x02,0x30,0x10,0x3b,0x51,0x60}, /* 640x400, 640x480 */ + {0x83,0x5d,0x21,0xbe,0x75,0x03,0x00,0x09,0x08,0x42,0x10,0x4d,0x61,0x79} /* 640x480u */ +}; +#ifdef TV6326TEST +const CARD8 SiS6326TVRegs1_NTSC_2[6][3] = { + { 0x00,0x00,0x00}, + { 0x00,0x00,0x00}, + { 0x24,0x92,0x49}, + { 0x24,0x92,0x49}, /* 8a50 */ + { 0x24,0x92,0x49}, /* 640x400, 640x480 */ /* 8afc */ + { 0x21,0xbe,0x75} /* 640x480u */ /* n/a */ +}; +#endif -/* local used for debug */ -static void -SiSModifyModeInfo(DisplayModePtr mode) -{ -/* - mode->Clock = 31500; - mode->CrtcHTotal = 832; - mode->CrtcHDisplay = 640; - mode->CrtcHBlankStart = 648; - mode->CrtcHSyncStart = 664; - mode->CrtcHSyncEnd = 704; - mode->CrtcHBlankEnd = 824; - - mode->CrtcVTotal = 520; - mode->CrtcVDisplay = 480; - mode->CrtcVBlankStart = 488; - mode->CrtcVSyncStart = 489; - mode->CrtcVSyncEnd = 492; - mode->CrtcVBlankEnd = 512; -*/ - if (mode->CrtcHBlankStart == mode->CrtcHDisplay) - mode->CrtcHBlankStart++; - if (mode->CrtcHBlankEnd == mode->CrtcHTotal) - mode->CrtcHBlankEnd--; - if (mode->CrtcVBlankStart == mode->CrtcVDisplay) - mode->CrtcVBlankStart++; - if (mode->CrtcVBlankEnd == mode->CrtcVTotal) - mode->CrtcVBlankEnd--; -} +const CARD8 SiS6326TVRegs2_NTSC[6][54] = { + {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, + 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94, + 0xFC, 0xDF, 0x94, 0x1F, 0x4A, 0x03, 0x71, 0x07, 0x97, 0x10, 0x40, + 0x48, 0x00, 0x26, 0xB6, 0x10, 0x5C, 0xEC, 0x21, 0x2E, 0xBE, 0x10, + 0x64, 0xF4, 0x21, 0x13, 0x75, 0x08, 0x31, 0x6A, 0x01, 0xA0}, + {0x11, 0x17, 0x03, 0x0A, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, + 0x0D, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94, + 0xFF, 0xDF, 0x94, 0x1F, 0x4A, 0x03, 0x71, 0x07, 0x97, 0x10, 0x40, + 0x48, 0x00, 0x26, 0xB6, 0x10, 0x5C, 0xEC, 0x21, 0x2E, 0xBE, 0x10, + 0x64, 0xF4, 0x21, 0x13, 0x75, 0x08, 0x31, 0x6A, 0x01, 0xA0}, + {0x11, 0x17, 0x03, 0x0A, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, + 0x0D, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94, + 0xFF, 0xDF, 0x94, 0x3F, 0x8C, 0x06, 0xCE, 0x07, 0x27, 0x30, 0x73, + 0x7B, 0x00, 0x48, 0x68, 0x30, 0xB2, 0xD2, 0x52, 0x50, 0x70, 0x30, + 0xBA, 0xDA, 0x52, 0xDC, 0x02, 0xD1, 0x53, 0xF7, 0x02, 0xA0}, + {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, + 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94, + 0xDC, 0xDF, 0x94, 0x3F, 0x8C, 0x06, 0xCE, 0x07, 0x27, 0x30, 0x73, + 0x7B, 0x00, 0x48, 0x68, 0x30, 0xB2, 0xD2, 0x52, 0x50, 0x70, 0x30, + 0xBA, 0xDA, 0x52, 0x00, 0x02, 0xF5, 0x53, 0xF7, 0x02, 0xA0}, + {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, + 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94, + 0xDC, 0xDF, 0x94, 0x3F, 0x8C, 0x06, 0xCE, 0x07, 0x27, 0x30, 0x73, + 0x7B, 0x00, 0x48, 0x68, 0x30, 0xB2, 0xD2, 0x52, 0x50, 0x70, 0x30, + 0xBA, 0xDA, 0x52, 0xDC, 0x02, 0xD1, 0x53, 0xF7, 0x02, 0xA0}, + {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, /* 640x480u */ + 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94, + 0xDC, 0xDF, 0x94, 0xAF, 0x95, 0x06, 0xDD, 0x07, 0x5F, 0x30, 0x7E, + 0x86, 0x00, 0x4C, 0xA4, 0x30, 0xE3, 0x3B, 0x62, 0x54, 0xAC, 0x30, + 0xEB, 0x43, 0x62, 0x48, 0x34, 0x3D, 0x63, 0x29, 0x03, 0xA0} +}; -static void -Find530Threshold(ScrnInfoPtr pScrn, int mclk, int vclk, int bpp, - int buswidth, int flags, int *low, int *high) -{ - int factor, z; - - *high = 0x1F; - if (flags & UMA) - factor = 0x60; - else - factor = 0x30; - z = factor * vclk * bpp; - z = z / mclk / buswidth; - *low = (z+1)/2 + 4; - if (*low > 0x1F) - *low = 0x1F; -} +const CARD8 SiS6326TVRegs1_PAL[6][14] = { + {0x81,0x2d,0xc8,0x07,0xb2,0x0b,0x00,0x09,0x02,0xed,0x00,0xf8,0x30,0x40}, + {0x80,0x2d,0xa4,0x03,0xd9,0x0b,0x00,0x09,0x02,0xed,0x10,0xf8,0x71,0x40}, + {0x81,0x2d,0xa4,0x03,0xd9,0x0b,0x00,0x09,0x02,0xed,0x10,0xf8,0x71,0x40}, /* 640x480 */ + {0x81,0x2d,0xa4,0x03,0xd9,0x0b,0x00,0x09,0x02,0x8f,0x10,0x9a,0x71,0x40}, /* 800x600 */ + {0x83,0x63,0xa1,0x7a,0xa3,0x0a,0x00,0x09,0x02,0xb5,0x11,0xc0,0x81,0x59}, /* 800x600u */ + {0x81,0x63,0xa4,0x03,0xd9,0x01,0x00,0x09,0x10,0x9f,0x10,0xaa,0x71,0x59} /* 720x540 */ +}; -struct funcargc { - char base; - char inc; +#ifdef TV6326TEST +const CARD8 SiS6326TVRegs1_PAL_2[6][3] = { + { 0x00,0x00,0x00}, + { 0x00,0x00,0x00}, + { 0xa4,0x07,0xd9}, /* 640x480 */ /* 887e */ + { 0xa4,0x08,0x19}, /* 800x600 */ /* 8828 */ + { 0xa1,0x7e,0xa3}, /* 800x600u */ /* n/a */ + { 0xa4,0x07,0xd9} /* 720x540 */ /* n/a */ }; +#endif -struct funcargc funca[12] = { - {61, 3}, {52, 5}, {68, 7}, {100, 11}, - {43, 3}, {42, 5}, {54, 7}, {78, 11}, - {34, 3}, {37, 5}, {47, 7}, {67, 11}}; +const CARD8 SiS6326TVRegs2_PAL[6][54] = { + {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, + 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94, + 0xE5, 0xDF, 0x94, 0xEF, 0x5A, 0x03, 0x7F, 0x07, 0xFF, 0x10, 0x4E, + 0x56, 0x00, 0x2B, 0x23, 0x20, 0xB4, 0xAC, 0x31, 0x33, 0x2B, 0x20, + 0xBC, 0xB4, 0x31, 0x83, 0xE1, 0x78, 0x31, 0xD6, 0x01, 0xA0}, + {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, + 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94, + 0xE5, 0xDF, 0x94, 0xDF, 0xB2, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x90, + 0x98, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40, + 0x6A, 0x5A, 0x73, 0x03, 0xC1, 0xF8, 0x63, 0xB6, 0x03, 0xA0}, + {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, /* 640x480 */ + 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94, + 0xE5, 0xDF, 0x94, 0xDF, 0xB2, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x90, + 0x98, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40, + 0x6A, 0x5A, 0x73, 0x03, 0xC1, 0xF8, 0x63, 0xB6, 0x03, 0xA0}, + {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, /* 800x600 */ + 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94, + 0xE5, 0xDF, 0x94, 0xDF, 0xB2, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x90, + 0x98, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40, + 0x6A, 0x5A, 0x73, 0xA0, 0xC1, 0x95, 0x73, 0xB6, 0x03, 0xA0}, + {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, /* 800x600u */ + 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94, + 0xE5, 0xDF, 0x94, 0x7F, 0xBD, 0x08, 0x0E, 0x07, 0x47, 0x40, 0x9D, + 0xA5, 0x00, 0x54, 0x94, 0x40, 0xA4, 0xE4, 0x73, 0x5C, 0x9C, 0x40, + 0xAC, 0xEC, 0x73, 0x0B, 0x0E, 0x00, 0x84, 0x03, 0x04, 0xA0}, + {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, /* 720x540 */ + 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94, + 0xE5, 0xDF, 0x94, 0xDF, 0xB0, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x9D, + 0xA5, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40, + 0x6A, 0x5A, 0x73, 0xA0, 0xC1, 0x95, 0x73, 0xB6, 0x03, 0xA0} +}; -struct funcargc funcb[12] = { - {81, 4}, {72, 6}, {88, 8}, {120, 12}, - {55, 4}, {54, 6}, {66, 8}, {90, 12}, - {42, 4}, {45, 6}, {55, 8}, {75, 12}}; -char timing[8] = {1, 2, 2, 3, 0, 1, 1, 2}; +const CARD8 SiS6326CR[9][15] = { + {0x79,0x63,0x64,0x1d,0x6a,0x93,0x00,0x6f,0xf0,0x58,0x8a,0x57,0x57,0x70,0x20}, /* PAL 800x600 */ + {0x79,0x4f,0x50,0x95,0x60,0x93,0x00,0x6f,0xba,0x14,0x86,0xdf,0xe0,0x30,0x00}, /* PAL 640x480 */ + {0x5f,0x4f,0x50,0x82,0x53,0x9f,0x00,0x0b,0x3e,0xe9,0x8b,0xdf,0xe7,0x04,0x00}, /* NTSC 640x480 */ + {0x5f,0x4f,0x50,0x82,0x53,0x9f,0x00,0x0b,0x3e,0xcb,0x8d,0x8f,0x96,0xe9,0x00}, /* NTSC 640x400 */ + {0x83,0x63,0x64,0x1f,0x6d,0x9b,0x00,0x6f,0xf0,0x48,0x0a,0x23,0x57,0x70,0x20}, /* PAL 800x600u */ + {0x79,0x59,0x5b,0x1d,0x66,0x93,0x00,0x6f,0xf0,0x42,0x04,0x1b,0x40,0x70,0x20}, /* PAL 720x540 */ + {0x66,0x4f,0x51,0x0a,0x57,0x89,0x00,0x0b,0x3e,0xd9,0x0b,0xb6,0xe7,0x04,0x00}, /* NTSC 640x480u */ + {0xce,0x9f,0x9f,0x92,0xa4,0x16,0x00,0x28,0x5a,0x00,0x04,0xff,0xff,0x29,0x39}, /* 1280x1024-75 */ + {0x09,0xc7,0xc7,0x0d,0xd2,0x0a,0x01,0xe0,0x10,0xb0,0x04,0xaf,0xaf,0xe1,0x1f} /* 1600x1200-60 */ +}; -static void -Find300_Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode) +/* Initialize a display mode on 5597/5598, 6326 and 530/620 */ +static Bool +SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { - SISPtr pSiS = SISPTR(pScrn); - SISRegPtr pReg = &pSiS->ModeReg; - int mclk = pSiS->MemClock; - int vclk = mode->Clock; - int bpp = pScrn->bitsPerPixel/8; - int lowa, lowb, low; - struct funcargc *p; - unsigned int i, j; - - pReg->sisRegs3C4[0x16] = pSiS->SavedReg.sisRegs3C4[0x16]; - - if (!bpp) bpp = 1; - - do { - i = ((pReg->sisRegs3C4[0x18] & 0x60) >> 4) | - ((pReg->sisRegs3C4[0x18] & 0x02) >> 1); - j = ((pReg->sisRegs3C4[0x14] & 0xC0) >> 4) | - (pReg->sisRegs3C4[0x16] >> 6); - p = &funca[j]; - - lowa = (p->base + p->inc*timing[i])*vclk*bpp; - lowa = (lowa + (mclk-1)) / mclk; - lowa = (lowa + 15)/16; - - p = &funcb[j]; - lowb = (p->base + p->inc*timing[i])*vclk*bpp; - lowb = (lowb + (mclk-1)) / mclk; - lowb = (lowb + 15)/16; - - if (lowb < 4) - lowb = 0; - else - lowb -= 4; - - low = (lowa > lowb)? lowa: lowb; - - low++; - - if (low <= 0x13) { - break; - } else { - i = (pReg->sisRegs3C4[0x16] >> 6) & 3; - if (!i) { - low = 0x13; - break; - } else { - i--; - pReg->sisRegs3C4[0x16] &= 0x3C; - pReg->sisRegs3C4[0x16] |= (i << 6); - } - } - } while (1); - - pReg->sisRegs3C4[0x08] = ((low & 0xF) << 4) | 0xF; - pReg->sisRegs3C4[0x0F] = (low & 0x10) << 1; - pReg->sisRegs3C4[0x09] &= 0xF0; - if (low+3 > 15) - pReg->sisRegs3C4[0x09] |= 0x0F; - else - pReg->sisRegs3C4[0x09] |= low + 3; -} + SISPtr pSiS = SISPTR(pScrn); + SISRegPtr pReg = &pSiS->ModeReg; + vgaRegPtr vgaReg = &VGAHWPTR(pScrn)->ModeReg; + unsigned char temp; + int mclk = pSiS->MemClock; + int offset; + int clock = mode->Clock; + int width = mode->HDisplay; + int height = mode->VDisplay; + int rate = SiSCalcVRate(mode); + int buswidth = pSiS->BusWidth; + unsigned int vclk[5]; + unsigned short CRT_CPUthresholdLow; + unsigned short CRT_CPUthresholdHigh; + unsigned short CRT_ENGthreshold; + double a, b, c; + int d, factor; + int num, denum, div, sbit, scale; + BOOL sis6326tvmode, sis6326himode; + + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "SISInit()\n")); + + /* Save the registers for further processing */ + (*pSiS->SiSSave)(pScrn, pReg); + + /* Determine if chosen mode is suitable for TV on the 6326 + * and if the mode is one of our special hi-res modes. + */ + sis6326tvmode = FALSE; + sis6326himode = FALSE; + if(pSiS->Chipset == PCI_CHIP_SIS6326) { + if(pSiS->SiS6326Flags & SIS6326_HASTV) { + if((pSiS->SiS6326Flags & SIS6326_TVDETECTED) && + ((strcmp(mode->name, "PAL800x600") == 0) || /* Special TV modes */ + (strcmp(mode->name, "PAL800x600U") == 0) || + (strcmp(mode->name, "PAL720x540") == 0) || + (strcmp(mode->name, "PAL640x480") == 0) || + (strcmp(mode->name, "NTSC640x480") == 0) || + (strcmp(mode->name, "NTSC640x480U") == 0) || + (strcmp(mode->name, "NTSC640x400") == 0))) { + sis6326tvmode = TRUE; + } else { + pReg->sis6326tv[0x00] &= 0xfb; + } + } + if((strcmp(mode->name, "SIS1280x1024-75") == 0) || /* Special high-res modes */ + (strcmp(mode->name, "SIS1600x1200-60") == 0)) { + sis6326himode = TRUE; + } + } -struct QConfig { - int GT; - int QC; -}; +#ifdef UNLOCK_ALWAYS + outSISIDXREG(SISSR, 0x05, 0x86); +#endif -struct QConfig qconfig[20] = { - {1, 0x0}, {1, 0x2}, {1, 0x4}, {1, 0x6}, {1, 0x8}, - {1, 0x3}, {1, 0x5}, {1, 0x7}, {1, 0x9}, {1, 0xb}, - {0, 0x0}, {0, 0x2}, {0, 0x4}, {0, 0x6}, {0, 0x8}, - {0, 0x3}, {0, 0x5}, {0, 0x7}, {0, 0x9}, {0, 0xb}}; + if(!pSiS->UseVESA) { + pReg->sisRegs3C4[0x06] &= 0x01; + } -int cycleA[20][2] = { - {88,88}, {80,80}, {78,78}, {72,72}, {70,70}, - {79,72}, {77,70}, {71,64}, {69,62}, {49,44}, - {73,78}, {65,70}, {63,68}, {57,62}, {55,60}, - {64,62}, {62,60}, {56,54}, {54,52}, {34,34}}; + /* set interlace */ + if(!(mode->Flags & V_INTERLACE)) { + offset = pSiS->CurrentLayout.displayWidth >> 3; + } else { + offset = pSiS->CurrentLayout.displayWidth >> 2; + if(!pSiS->UseVESA) { + pReg->sisRegs3C4[0x06] |= 0x20; + } + } -static void -Find630_Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - SISPtr pSiS = SISPTR(pScrn); - SISRegPtr pReg = &pSiS->ModeReg; - int mclk = pSiS->MemClock; - int vclk = mode->Clock; - int bpp = pScrn->bitsPerPixel/8; - CARD32 temp; - PCITAG NBridge; - int low, lowa, cyclea; - int i, j; - - if (!bpp) bpp = 1; - - i = 0; - j = (pReg->sisRegs3C4[0x14] >> 6) - 1; - - while (1) { -#ifdef DEBUG - ErrorF("Config %d GT = %d, QC = %x, CycleA = %d\n", - i, qconfig[i].GT, qconfig[i].QC, cycleA[i][j]); + /* Enable Linear and Enhanced Gfx Mode */ + if(!pSiS->UseVESA) { + pReg->sisRegs3C4[0x06] |= 0x82; + } + + /* Enable MMIO at PCI Register 14H (D[6:5]: 11) */ + if(pSiS->oldChipset >= OC_SIS5597) { + pReg->sisRegs3C4[0x0B] |= 0x60; + } else { + pReg->sisRegs3C4[0x0B] |= 0x20; + pReg->sisRegs3C4[0x0B] &= ~0x40; + } + + if(!pSiS->UseVESA) { + + /* Enable 32bit mem access (D7), read-ahead cache (D5) */ + pReg->sisRegs3C4[0x0C] |= 0x80; + if(pSiS->oldChipset > OC_SIS6225) { + pReg->sisRegs3C4[0x0C] |= 0x20; + } + + /* Some speed-up stuff */ + switch(pSiS->Chipset) { + case PCI_CHIP_SIS5597: + /* enable host bus */ + if(pSiS->NoHostBus) { + pReg->sisRegs3C4[0x34] &= ~0x08; + } else { + pReg->sisRegs3C4[0x34] |= 0x08; + } + /* fall through */ + case PCI_CHIP_SIS6326: + case PCI_CHIP_SIS530: + /* Enable "dual segment register mode" (D2) and "i/o gating while + * write buffer is not empty" (D3) + */ + pReg->sisRegs3C4[0x0B] |= 0x0C; + } + + /* set colordepth */ + if(pSiS->Chipset == PCI_CHIP_SIS530) { + pReg->sisRegs3C4[0x09] &= 0x7F; + } + switch(pSiS->CurrentLayout.bitsPerPixel) { + case 8: + break; + case 16: + offset <<= 1; + if(pSiS->CurrentLayout.depth == 15) + pReg->sisRegs3C4[0x06] |= 0x04; + else + pReg->sisRegs3C4[0x06] |= 0x08; + break; + case 24: + offset += (offset << 1); + pReg->sisRegs3C4[0x06] |= 0x10; + pReg->sisRegs3C4[0x0B] |= 0x90; + break; + case 32: + if(pSiS->Chipset == PCI_CHIP_SIS530) { + offset <<= 2; + if(pSiS->oldChipset != OC_SIS620) { + pReg->sisRegs3C4[0x06] |= 0x10; + } + pReg->sisRegs3C4[0x0B] |= 0x90; + pReg->sisRegs3C4[0x09] |= 0x80; + } else return FALSE; + break; + } + } + + /* save screen pitch for acceleration functions */ + pSiS->scrnOffset = pSiS->CurrentLayout.displayWidth * + ((pSiS->CurrentLayout.bitsPerPixel + 7) / 8); + + if(!pSiS->UseVESA) { + + /* set linear framebuffer addresses */ + switch(pScrn->videoRam) { + case 512: temp = 0x00; break; + case 1024: temp = 0x20; break; + case 2048: temp = 0x40; break; + case 4096: temp = 0x60; break; + case 8192: temp = 0x80; break; + default: temp = 0x20; + } + pReg->sisRegs3C4[0x20] = (pSiS->FbAddress & 0x07F80000) >> 19; + pReg->sisRegs3C4[0x21] = ((pSiS->FbAddress & 0xF8000000) >> 27) | temp; + + /* Set screen offset */ + vgaReg->CRTC[0x13] = offset & 0xFF; + + /* Set CR registers for our built-in TV and hi-res modes */ + if((sis6326tvmode) || (sis6326himode)) { + + int index,i; + + /* We need our very private data for hi-res and TV modes */ + if(sis6326himode) { + if(strcmp(mode->name, "SIS1280x1024-75") == 0) index = 7; + else index = 8; + } else { + if(pSiS->SiS6326Flags & SIS6326_TVPAL) { + switch(width) { + case 800: + if((strcmp(mode->name, "PAL800x600U") == 0)) + index = 4; + else + index = 0; + break; + case 720: + index = 5; + break; + case 640: + default: + index = 1; + } + } else { + switch(height) { + case 400: + index = 3; + break; + case 480: + default: + if((strcmp(mode->name, "NTSC640x480U") == 0)) + index = 6; + else + index = 2; + } + } + } + for(i=0; i<=5; i++) { + vgaReg->CRTC[i] = SiS6326CR[index][i]; + } + pReg->sisRegs3C4[0x12] = SiS6326CR[index][6]; + vgaReg->CRTC[6] = SiS6326CR[index][7]; + vgaReg->CRTC[7] = SiS6326CR[index][8]; + vgaReg->CRTC[0x10] = SiS6326CR[index][9]; + vgaReg->CRTC[0x11] = SiS6326CR[index][10]; + vgaReg->CRTC[0x12] = SiS6326CR[index][11]; + vgaReg->CRTC[0x15] = SiS6326CR[index][12]; + vgaReg->CRTC[0x16] = SiS6326CR[index][13]; + vgaReg->CRTC[9] &= ~0x20; + vgaReg->CRTC[9] |= (SiS6326CR[index][14] & 0x20); + pReg->sisRegs3C4[0x0A] = ((offset & 0xF00) >> 4) | (SiS6326CR[index][14] & 0x0f); + + } else { + + /* Set extended vertical overflow register */ + pReg->sisRegs3C4[0x0A] = ((offset & 0xF00) >> 4) | + (((mode->CrtcVTotal-2) & 0x400) >> 10 ) | + (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) | +/* (((mode->CrtcVSyncStart-1) & 0x400) >> 8 ) | */ + (((mode->CrtcVBlankStart-1)& 0x400) >> 8 ) | +/* (((mode->CrtcVBlankStart-1)& 0x400) >> 7 ); */ + (((mode->CrtcVSyncStart) & 0x400) >> 7 ); + + /* Set extended horizontal overflow register */ + pReg->sisRegs3C4[0x12] &= 0xE0; + pReg->sisRegs3C4[0x12] |= ( + (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8 | + (((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7 | +/* (((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6 | */ + (((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 6 | + ((mode->CrtcHSyncStart >> 3) & 0x100) >> 5 | + (((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 2); + } + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "HDisplay %d HSyncStart %d HSyncEnd %d HTotal %d\n", + mode->CrtcHDisplay, mode->CrtcHSyncStart, + mode->CrtcHSyncEnd, mode->CrtcHTotal); + xf86DrvMsg(0, X_INFO, "HBlankSt %d HBlankE %d\n", + mode->CrtcHBlankStart, mode->CrtcHBlankEnd); + + xf86DrvMsg(0, X_INFO, "VDisplay %d VSyncStart %d VSyncEnd %d VTotal %d\n", + mode->CrtcVDisplay, mode->CrtcVSyncStart, + mode->CrtcVSyncEnd, mode->CrtcVTotal); + xf86DrvMsg(0, X_INFO, "VBlankSt %d VBlankE %d\n", + mode->CrtcVBlankStart, mode->CrtcVBlankEnd); #endif - cyclea = cycleA[i][j]; - lowa = cyclea * vclk * bpp; - lowa = (lowa + (mclk-1)) / mclk; - lowa = (lowa + 15) / 16; - low = lowa + 1; - if (low <= 0x13) - break; - else - if (i < 19) - i++; - else { - low = 0x13; -#ifdef DEBUG - ErrorF("This mode may has threshold problem and had better removed\n"); + + /* enable (or disable) line compare */ + if(mode->CrtcVDisplay >= 1024) + pReg->sisRegs3C4[0x38] |= 0x04; + else + pReg->sisRegs3C4[0x38] &= 0xFB; + + /* Enable (or disable) high speed DCLK (some 6326 and 530/620 only) */ + if( ( (pSiS->Chipset == PCI_CHIP_SIS6326) && + ( (pSiS->ChipRev == 0xd0) || (pSiS->ChipRev == 0xd1) || + (pSiS->ChipRev == 0xd2) || (pSiS->ChipRev == 0x92) || + (pSiS->Flags & A6326REVAB) ) ) || + (pSiS->oldChipset > OC_SIS6326) ) { + if( (pSiS->CurrentLayout.bitsPerPixel == 24) || + (pSiS->CurrentLayout.bitsPerPixel == 32) || + (mode->CrtcHDisplay >= 1280) ) + pReg->sisRegs3C4[0x3E] |= 0x01; + else + pReg->sisRegs3C4[0x3E] &= 0xFE; + } + + /* We use the internal VCLK */ + pReg->sisRegs3C4[0x38] &= 0xFC; + + /* Programmable Clock */ + pReg->sisRegs3C2 = inb(SISMISCR) | 0x0C; + + if(pSiS->oldChipset <= OC_SIS86202) { + /* TODO: Handle SR07 for clock selection */ + /* 86C201 does not even have a programmable clock... */ + /* pReg->sisRegs3C4[0x07] &= 0x??; */ + } + + /* Set VCLK */ + if((sis6326tvmode) || (sis6326himode)) { + + /* For our built-in modes, the calculation is not suitable */ + if(sis6326himode) { + if((strcmp(mode->name, "SIS1280x1024-75") == 0)) { + pReg->sisRegs3C4[0x2A] = 0x5d; /* 1280x1024-75 */ + pReg->sisRegs3C4[0x2B] = 0xa4; + } else { + pReg->sisRegs3C4[0x2A] = 0x59; /* 1600x1200-60 */ + pReg->sisRegs3C4[0x2B] = 0xa3; + } + pReg->sisRegs3C4[0x13] &= ~0x40; + } else { + if(pSiS->SiS6326Flags & SIS6326_TVPAL) { + /* PAL: 31.500 Mhz */ + if((strcmp(mode->name, "PAL800x600U") == 0)) { + pReg->sisRegs3C4[0x2A] = 0x46; + pReg->sisRegs3C4[0x2B] = 0x49; + } else { + pReg->sisRegs3C4[0x2A] = 0xab; + pReg->sisRegs3C4[0x2B] = 0xe9; + } + pReg->sisRegs3C4[0x13] &= ~0x40; + } else { + /* NTSC: 27.000 Mhz */ + if((strcmp(mode->name, "NTSC640x480U") == 0)) { + pReg->sisRegs3C4[0x2A] = 0x5a; + pReg->sisRegs3C4[0x2B] = 0x65; + } else { + pReg->sisRegs3C4[0x2A] = 0x29; + pReg->sisRegs3C4[0x2B] = 0xe2; + } + pReg->sisRegs3C4[0x13] |= 0x40; + } + } + + } else if(SiS_compute_vclk(clock, &num, &denum, &div, &sbit, &scale)) { + + pReg->sisRegs3C4[0x2A] = (num - 1) & 0x7f ; + pReg->sisRegs3C4[0x2A] |= (div == 2) ? 0x80 : 0; + pReg->sisRegs3C4[0x2B] = ((denum - 1) & 0x1f); + pReg->sisRegs3C4[0x2B] |= (((scale -1) & 3) << 5); + + /* When setting VCLK, we should set SR13 first */ + if(sbit) + pReg->sisRegs3C4[0x13] |= 0x40; + else + pReg->sisRegs3C4[0x13] &= 0xBF; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "2a: %x 2b: %x 13: %x clock %d\n", + pReg->sisRegs3C4[0x2A], pReg->sisRegs3C4[0x2B], pReg->sisRegs3C4[0x13], clock); #endif - break; - } - } -#ifdef DEBUG - ErrorF("Using Config %d with CycleA = %d\n", i, cyclea); + + } else { + + /* if SiS_compute_vclk cannot handle the requested clock, try sisCalcClock */ + SiSCalcClock(pScrn, clock, 2, vclk); + +#define Midx 0 +#define Nidx 1 +#define VLDidx 2 +#define Pidx 3 +#define PSNidx 4 + + pReg->sisRegs3C4[0x2A] = (vclk[Midx] - 1) & 0x7f; + pReg->sisRegs3C4[0x2A] |= ((vclk[VLDidx] == 2) ? 1 : 0) << 7; + + /* bits [4:0] contain denumerator */ + pReg->sisRegs3C4[0x2B] = (vclk[Nidx] - 1) & 0x1f; + + if(vclk[Pidx] <= 4){ + /* postscale 1,2,3,4 */ + pReg->sisRegs3C4[0x2B] |= (vclk[Pidx] - 1) << 5; + pReg->sisRegs3C4[0x13] &= 0xBF; + } else { + /* postscale 6,8 */ + pReg->sisRegs3C4[0x2B] |= ((vclk[Pidx] / 2) - 1) << 5; + pReg->sisRegs3C4[0x13] |= 0x40; + } + pReg->sisRegs3C4[0x2B] |= 0x80 ; /* gain for high frequency */ + + } + + /* High speed DAC */ + if(clock > 135000) + pReg->sisRegs3C4[0x07] |= 0x02; + + if(pSiS->oldChipset > OC_SIS6225) { + /* 1 or 2 cycle DRAM (set by option FastVram) */ + if(pSiS->newFastVram == -1) { + if(pSiS->oldChipset == OC_SIS620) { + /* Use different default on the 620 */ + pReg->sisRegs3C4[0x34] |= 0x40; + pReg->sisRegs3C4[0x34] &= ~0x80; + } else { + pReg->sisRegs3C4[0x34] |= 0x80; + pReg->sisRegs3C4[0x34] &= ~0x40; + } + } else if(pSiS->newFastVram == 1) + pReg->sisRegs3C4[0x34] |= 0xC0; + else + pReg->sisRegs3C4[0x34] &= ~0xC0; + + if(pSiS->oldChipset == OC_SIS620) { + /* Enable SGRAM burst timing (= bit clear) on the 620 */ + if(pSiS->Flags & SYNCDRAM) { + pReg->sisRegs3C4[0x35] &= ~0x20; + } else { + pReg->sisRegs3C4[0x35] |= 0x20; + } + } + } + + } /* VESA */ + + /* Logical line length */ + pSiS->ValidWidth = TRUE; + pReg->sisRegs3C4[0x27] &= 0xCF; + if(pSiS->CurrentLayout.bitsPerPixel == 24) { + /* Invalid logical width */ + pReg->sisRegs3C4[0x27] |= 0x30; + pSiS->ValidWidth = FALSE; + } else { + switch(pScrn->virtualX * (pSiS->CurrentLayout.bitsPerPixel >> 3)) { + case 1024: + pReg->sisRegs3C4[0x27] |= 0x00; + break; + case 2048: + pReg->sisRegs3C4[0x27] |= 0x10; + break; + case 4096: + pReg->sisRegs3C4[0x27] |= 0x20; + break; + default: + /* Invalid logical width */ + pReg->sisRegs3C4[0x27] |= 0x30; + pSiS->ValidWidth = FALSE; + break; + } + } + + /* Acceleration stuff */ + if(!pSiS->NoAccel) { + pReg->sisRegs3C4[0x27] |= 0x40; /* Enable engine programming registers */ + if( (pSiS->TurboQueue) && /* Handle TurboQueue */ + (pSiS->oldChipset > OC_SIS6225) && + ( (pSiS->Chipset != PCI_CHIP_SIS530) || + (pSiS->CurrentLayout.bitsPerPixel != 24) ) ) { + pReg->sisRegs3C4[0x27] |= 0x80; /* Enable TQ */ + if((pSiS->Chipset == PCI_CHIP_SIS530) || + ((pSiS->Chipset == PCI_CHIP_SIS6326 && + (pSiS->ChipRev == 0xd0 || pSiS->ChipRev == 0xd1 || + pSiS->ChipRev == 0xd2 || pSiS->ChipRev == 0x92 || + pSiS->ChipRev == 0x0a || pSiS->ChipRev == 0x1a || + pSiS->ChipRev == 0x2a || pSiS->ChipRev == 0x0b || + pSiS->ChipRev == 0x1b || pSiS->ChipRev == 0x2b) ) ) ) { + /* pReg->sisRegs3C4[0x3D] |= 0x80; */ /* Queue is 62K (530/620 specs) */ + pReg->sisRegs3C4[0x3D] &= 0x7F; /* Queue is 30K (530/620 specs) */ + } + /* Locate the TQ at the beginning of the last 64K block of + * video RAM. The address is to be specified in 32K steps. + */ + pReg->sisRegs3C4[0x2C] = (pScrn->videoRam - 64) / 32; + if(pSiS->Chipset != PCI_CHIP_SIS530) { /* 530/620: Reserved (don't touch) */ + pReg->sisRegs3C4[0x3C] &= 0xFC; /* 6326: Queue is all for 2D */ + } /* 5597: Must be 0 */ + } else { + pReg->sisRegs3C4[0x27] &= 0x7F; + } + } + + + if(!pSiS->UseVESA) { + + /* TW: No idea what this does. The Windows driver does it, so we do it as well */ + if(pSiS->Chipset == PCI_CHIP_SIS6326) { + if((pSiS->ChipRev == 0xd0) || (pSiS->ChipRev == 0xd1) || + (pSiS->ChipRev == 0xd2) || (pSiS->ChipRev == 0x92) || + (pSiS->Flags & A6326REVAB)) { + if((pSiS->Flags & (SYNCDRAM | RAMFLAG)) == (SYNCDRAM | RAMFLAG)) { + if(!(pReg->sisRegs3C4[0x0E] & 0x03)) { + pReg->sisRegs3C4[0x3E] |= 0x02; + } + } + } + } + + /* Set memclock */ +#if 0 + /* We don't need to do this; the SetMClk option was not used since 4.0. */ + if((pSiS->Chipset == PCI_CHIP_SIS5597) || (pSiS->Chipset == PCI_CHIP_SIS6326)) { + if(pSiS->MemClock > 66000) { + SiSCalcClock(pScrn, pSiS->MemClock, 1, vclk); + + pReg->sisRegs3C4[0x28] = (vclk[Midx] - 1) & 0x7f ; + pReg->sisRegs3C4[0x28] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; + pReg->sisRegs3C4[0x29] = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */ + if(vclk[Pidx] <= 4) { + pReg->sisRegs3C4[0x29] |= (vclk[Pidx] - 1) << 5 ; /* postscale 1,2,3,4 */ + pReg->sisRegs3C4[0x13] &= 0x7F; + } else { + pReg->sisRegs3C4[0x29] |= ((vclk[Pidx] / 2) - 1) << 5 ; /* postscale 6,8 */ + pReg->sisRegs3C4[0x13] |= 0x80; + } + /* Check programmed memory clock. Enable only to check the above code */ +/* + mclk = 14318 * ((pReg->sisRegs3C4[0x28] & 0x7f) + 1); + mclk /= ((pReg->sisRegs3C4[0x29] & 0x0f) + 1); + if(!(pReg->sisRegs3C4[0x13] & 0x80)) { + mclk /= (((pReg->sisRegs3C4[0x29] & 0x60) >> 5) + 1); + } else { + if((pReg->sisRegs3C4[0x29] & 0x60) == 0x40) mclk /= 6; + if((pReg->sisRegs3C4[0x29] & 0x60) == 0x60) mclk /= 8; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,2, + "Setting memory clock to %.3f MHz\n", + mclk/1000.0); +*/ + } + } #endif - pReg->sisRegs3C4[0x08] = ((low & 0xF) << 4) | 0xF; - pReg->sisRegs3C4[0x0F] &= 0xDF; - pReg->sisRegs3C4[0x0F] |= (low & 0x10) << 1; - pReg->sisRegs3C4[0x09] &= 0xF0; - if (lowa+4 > 15) - pReg->sisRegs3C4[0x09] |= 0x0F; - else - pReg->sisRegs3C4[0x09] |= (lowa+4); - - /* write PCI configuration space */ - NBridge = pciTag(0, 0, 0); - temp = pciReadLong(NBridge, 0x50); - temp &= 0xF0FFFFFF; - temp |= qconfig[i].QC << 24; - pciWriteLong(NBridge, 0x50, temp); - - temp = pciReadLong(NBridge, 0xA0); - temp &= 0xF0FFFFFF; - temp |= qconfig[i].GT << 24; - pciWriteLong(NBridge, 0xA0, temp); - -#ifdef DEBUG - temp = pciReadLong(NBridge, 0x50); - ErrorF("QueueConfig: 0x80000050 = %x\n", temp); - temp = pciReadLong(NBridge, 0xA0); - ErrorF("QueueConfig: 0x800000A0 = %x\n", temp); + + /* Set threshold values */ + /* + * CPU/CRT Threshold: FIFO + * MCLK ___________ VCLK + * cpu/engine <---o o--------->|___________| -----------> CRT + * ^ ^ ^ ^ + * \ / | | + * \ / |< gap >| + * \ / | | + * selector switch Thrsh. low high + * + * CRT consumes the data in the FIFO during scanline display. When the + * amount of data in the FIFO reaches the Threshold low value, the selector + * switch will switch to the right, and the FIFO will be refilled with data. + * When the amount of data in the FIFO reaches the Threshold high value, the + * selector switch will switch to the left and allows the CPU and the chip + * engines to access the video RAM. + * + * The Threshold low values should be increased at higher bpps, simply because + * there is more data needed for the CRT. When Threshold low and high are very + * close to each other, the selector switch will be activated more often, which + * decreases performance. + * + */ + switch(pSiS->Chipset) { + case PCI_CHIP_SIS5597: factor = 65; break; + case PCI_CHIP_SIS6326: factor = 30; break; + case PCI_CHIP_SIS530: factor = (pSiS->Flags & UMA) ? 60 : 30; break; + default: factor = (pScrn->videoRam > 1024) ? 24 : 12; + } + a = width * height * rate * 1.40 * factor * ((pSiS->CurrentLayout.bitsPerPixel + 1) / 8); + b = (mclk / 1000) * 999488.0 * (buswidth / 8); + c = ((a / b) + 1.0) / 2; + d = (int)c + 2; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, + "Debug: w %d h %d r %d mclk %d bus %d factor %d bpp %d\n", + width, height, rate, mclk/1000, buswidth, factor, + pSiS->CurrentLayout.bitsPerPixel); + xf86DrvMsg(0, X_INFO, "Debug: a %f b %f c %f d %d (flags %x)\n", + a, b, c, d, pSiS->Flags); #endif + CRT_CPUthresholdLow = d; + if((pSiS->Flags & (RAMFLAG | SYNCDRAM)) == (RAMFLAG | SYNCDRAM)) { + CRT_CPUthresholdLow += 2; + } + CRT_CPUthresholdHigh = CRT_CPUthresholdLow + 3; + + CRT_ENGthreshold = 0x0F; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "Debug: Thlow %d thhigh %d\n", + CRT_CPUthresholdLow, CRT_CPUthresholdHigh); +#endif + +#if 0 /* See comment in sis_dac.c on why this is commented */ + if(pSiS->Chipset == PCI_CHIP_SIS530) { + if((pSiS->oldChipset == OC_SIS530A) && + (pSiS->Flags & UMA) && + (mclk == 100000) && + (pSiS->Flags & ESS137xPRESENT)) { + if(!(pSiS->Flags & SECRETFLAG)) index = 0; + if((temp = SiS_CalcSpecial530Threshold(pSiS, mode, index)) { + CRT_CPUthresholdLow = temp; + break; + } + } + } +#endif + + switch(pSiS->Chipset) { + case PCI_CHIP_SIS530: + if(CRT_CPUthresholdLow > 0x1f) CRT_CPUthresholdLow = 0x1f; + CRT_CPUthresholdHigh = 0x1f; + break; + case PCI_CHIP_SIS5597: + case PCI_CHIP_SIS6326: + default: + if(CRT_CPUthresholdLow > 0x0f) CRT_CPUthresholdLow = 0x0f; + if(CRT_CPUthresholdHigh > 0x0f) CRT_CPUthresholdHigh = 0x0f; + } + + pReg->sisRegs3C4[0x08] = ((CRT_CPUthresholdLow & 0x0F) << 4) | + (CRT_ENGthreshold & 0x0F); + + pReg->sisRegs3C4[0x09] &= 0xF0; + pReg->sisRegs3C4[0x09] |= (CRT_CPUthresholdHigh & 0x0F); + + pReg->sisRegs3C4[0x3F] &= 0xEB; + pReg->sisRegs3C4[0x3F] |= (CRT_CPUthresholdHigh & 0x10) | + ((CRT_CPUthresholdLow & 0x10) >> 2); + + if(pSiS->oldChipset >= OC_SIS530A) { + pReg->sisRegs3C4[0x3F] &= 0xDF; + pReg->sisRegs3C4[0x3F] |= 0x58; + } + + /* Set SiS6326 TV registers */ + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (sis6326tvmode)) { + unsigned char tmp; + int index=0, i, j, k; + int fsc; + + if(pSiS->SiS6326Flags & SIS6326_TVPAL) { + pReg->sisRegs3C4[0x0D] |= 0x04; + switch(width) { + case 800: + if((strcmp(mode->name, "PAL800x600U") == 0)) index = 4; + else index = 3; + break; + case 720: index = 5; break; + case 640: + default: index = 2; + } + for(i=0; i<14; i++) { + pReg->sis6326tv[SiS6326TVRegs1[i]] = SiS6326TVRegs1_PAL[index][i]; + } +#ifdef TV6326TEST + for(i=0, j=2; i<3; i++, j++) { + pReg->sis6326tv[j] = SiS6326TVRegs1_PAL_2[index][i]; + } +#endif + fsc = (SiS6326TVRegs1_PAL[index][2] << 16) | + (SiS6326TVRegs1_PAL[index][3] << 8) | + (SiS6326TVRegs1_PAL[index][4]); + } else { + pReg->sisRegs3C4[0x0D] &= ~0x04; + if((strcmp(mode->name, "NTSC640x480U") == 0)) index = 5; + else index = 4; + for(i=0; i<14; i++) { + pReg->sis6326tv[SiS6326TVRegs1[i]] = SiS6326TVRegs1_NTSC[index][i]; + } +#ifdef TV6326TEST + for(i=0, j=2; i<3; i++, j++) { + pReg->sis6326tv[j] = SiS6326TVRegs1_NTSC_2[index][i]; + } +#endif + fsc = (SiS6326TVRegs1_NTSC[index][2] << 16) | + (SiS6326TVRegs1_NTSC[index][3] << 8) | + (SiS6326TVRegs1_NTSC[index][4]); + } + if(pSiS->sis6326fscadjust) { + fsc += pSiS->sis6326fscadjust; + pReg->sis6326tv[2] = (fsc >> 16) & 0xff; + pReg->sis6326tv[3] = (fsc >> 8) & 0xff; + pReg->sis6326tv[4] = fsc & 0xff; + } + tmp = pReg->sis6326tv[0x43]; + if(pSiS->SiS6326Flags & SIS6326_TVCVBS) tmp |= 0x10; + tmp |= 0x08; + pReg->sis6326tv[0x43] = tmp; + j = 0; k = 0; + for(i=0; i<=0x44; i++) { + if(SiS6326TVRegs1[j] == i) { + j++; + continue; + } + if(pSiS->SiS6326Flags & SIS6326_TVPAL) { + tmp = SiS6326TVRegs2_PAL[index][k]; + } else { + tmp = SiS6326TVRegs2_NTSC[index][k]; + } + pReg->sis6326tv[i] = tmp; + k++; + } + pReg->sis6326tv[0x43] |= 0x08; + if((pSiS->ChipRev == 0xc1) || (pSiS->ChipRev == 0xc2)) { + pReg->sis6326tv[0x43] &= ~0x08; + } + + tmp = pReg->sis6326tv[0]; + tmp |= 0x18; + if(pSiS->SiS6326Flags & SIS6326_TVCVBS) tmp &= ~0x10; + if(pSiS->SiS6326Flags & SIS6326_TVSVIDEO) tmp &= ~0x08; + tmp |= 0x04; + pReg->sis6326tv[0] = tmp; + } + + } /* VESA */ + + return(TRUE); } -static Bool -SiSInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +/* Init a mode for SiS 300, 315 and 330 series + * This function is now only used for setting up some + * variables (eg. scrnOffset). + */ +Bool +SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode) { - SISPtr pSiS = SISPTR(pScrn); - SISRegPtr pReg = &pSiS->ModeReg; - int gap, safetymargin, MemBand; - int vgaIOBase; - unsigned char temp, SR5State; - unsigned short temp1; - int Base,mclk; - int offset; - int clock = mode->Clock; - unsigned int vclk[5]; - int CRT_CPUthresholdLow ; - int CRT_CPUthresholdHigh ; - unsigned int CRT_ENGthreshold ; - - int num, denum, div, sbit, scale; - - PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "SiSInit()\n")); - vgaHWGetIOBase(VGAHWPTR(pScrn)); - vgaIOBase = VGAHWPTR(pScrn)->IOBase; - - SiSSave(pScrn, pReg); - - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - SR5State = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); - - pSiS->scrnOffset = pScrn->displayWidth * pScrn->bitsPerPixel / 8; - if ((mode->Flags & V_INTERLACE)==0) { - offset = pScrn->displayWidth >> 3; - pReg->sisRegs3C4[0x06] &= 0xDF; - } else { - offset = pScrn->displayWidth >> 2; - pReg->sisRegs3C4[0x06] |= 0x20; - } + SISPtr pSiS = SISPTR(pScrn); + SISRegPtr pReg = &pSiS->ModeReg; + unsigned short temp; + DisplayModePtr realmode = mode; +#ifdef SISMERGED + DisplayModePtr realmode2 = NULL; +#endif - /* Enable Linear */ - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - pReg->sisRegs3C4[BankReg] |= 0x82; - pReg->sisRegs3C4[0x0C] |= 0xA0; - pReg->sisRegs3C4[0x0B] |= 0x60; - break; - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - pReg->sisRegs3C4[0x20] |= 0x81; - pReg->sisRegs3C4[0x06] |= 0x02; - break; - default: - pReg->sisRegs3C4[BankReg] |= 0x82; - } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "SIS300Init()\n"); - switch (pScrn->bitsPerPixel) { - case 8: - pSiS->DstColor = 0x0000; - break; - case 15: - pSiS->DstColor = 0x4000; - offset <<= 1; - pReg->sisRegs3C4[BankReg] |= 0x04; - break; - case 16: - pSiS->DstColor = (short)0x8000; - offset <<= 1; - pReg->sisRegs3C4[BankReg] |= 0x08; - break; - case 24: - offset += (offset << 1); - switch (pSiS->Chipset) { - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - pReg->sisRegs3C4[0x06] |= 0x0C; - break; - default: - pReg->sisRegs3C4[BankReg] |= 0x10; - pReg->sisRegs3C4[MMIOEnable] |= 0x90; - } - break; - case 32: - pSiS->DstColor = (short)0xC000; - offset <<= 2; - switch (pSiS->Chipset) { - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - pReg->sisRegs3C4[0x06] &= 0xE3; - pReg->sisRegs3C4[0x06] |= 0x10; - break; - case PCI_CHIP_SIS530: - pReg->sisRegs3C4[BankReg] |= 0x10; - pReg->sisRegs3C4[MMIOEnable] |= 0x90; - pReg->sisRegs3C4[0x09] |= 0x80; - default: - return FALSE; - } - break; - } - switch (pScrn->videoRam) { - case 512: - temp = 0x00; - break; - case 1024: - temp = 0x20; - break; - case 2048: - temp = 0x40; - break; - case 4096: - temp = 0x60; - break; - case 8192: - temp = 0x80; - break; - default: - temp = 0x20; - } - switch (pSiS->Chipset) { - case PCI_CHIP_SG86C225: - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - pReg->sisRegs3C4[LinearAdd0] = (pSiS->FbAddress & 0x07F80000) >> 19; - pReg->sisRegs3C4[LinearAdd1] =((pSiS->FbAddress & 0xF8000000) >> 27) - | temp; /* Enable linear with max 4M */ - break; - case PCI_CHIP_SIS530: - pReg->sisRegs3C4[LinearAdd0] = (pSiS->FbAddress & 0x07F80000) >> 19; - pReg->sisRegs3C4[LinearAdd1] =((pSiS->FbAddress & 0xF8000000) >> 27) - | temp; /* Enable linear with max 8M */ - break; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "virtualX = %d depth = %d Logical width = %d\n", + pScrn->virtualX, pSiS->CurrentLayout.bitsPerPixel, + pScrn->virtualX * pSiS->CurrentLayout.bitsPerPixel/8); + +#ifdef SISMERGED + if(pSiS->MergedFB) { + realmode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1; + realmode2 = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; } +#endif - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - /* Screen Offset */ - pReg->sisRegs3x4[Offset] = offset & 0xFF; - pReg->sisRegs3C4[CRTCOff] = ((offset & 0xF00) >> 4) | - (((mode->CrtcVTotal-2) & 0x400) >> 10 ) | - (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) | - (((mode->CrtcVSyncStart-1) & 0x400) >> 8 ) | - (((mode->CrtcVSyncStart) & 0x400) >> 7 ) ; - - /* Extended Horizontal Overflow Register */ - pReg->sisRegs3C4[0x12] &= 0xE0; - pReg->sisRegs3C4[0x12] |= ( - (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8 | - (((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7 | - (((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6 | - ((mode->CrtcHSyncStart >> 3) & 0x100) >> 5 | - ((mode->CrtcHSyncEnd >> 3) & 0x40) >> 2); - - if (mode->CrtcVDisplay > 1024) - /* disable line compare */ - pReg->sisRegs3C4[0x38] |= 0x04; - else - pReg->sisRegs3C4[0x38] &= 0xFB; + /* Copy current register settings to structure */ + (*pSiS->SiSSave)(pScrn, pReg); - if (( pScrn->depth == 24) || (pScrn->depth == 32) || - (mode->CrtcHDisplay >= 1280)) - /* Enable high speed DCLK */ - pReg->sisRegs3C4[0x3E] |= 1; - else - pReg->sisRegs3C4[0x3E] &= 0xFE; - break; - - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - /* Screen Offset */ - pReg->sisRegs3x4[Offset] = offset & 0xFF; - pReg->sisRegs3C4[0x0E] &= 0xF0; - pReg->sisRegs3C4[0x0E] |= ((offset & 0xF00) >> 8); - - pReg->sisRegs3C4[0x10] = - ((mode->CrtcHDisplay *(pScrn->bitsPerPixel >>3) + 63) >> 6) +1; - pReg->sisRegs3C4[0x06] |= 0x01; - - /* Extended Vertical Overflow */ - pReg->sisRegs3C4[0x0A] = - (((mode->CrtcVTotal -2) & 0x400) >> 10) | - (((mode->CrtcVDisplay -1) & 0x400) >> 9 ) | - (((mode->CrtcVBlankStart ) & 0x400) >> 8 ) | - (((mode->CrtcVSyncStart ) & 0x400) >> 7 ) | - (((mode->CrtcVBlankEnd ) & 0x100) >> 4 ) | - (((mode->CrtcVSyncEnd ) & 0x010) << 1 ); - - /* Extended Horizontal Overflow */ - pReg->sisRegs3C4[0x0B] = - (((mode->CrtcHTotal >> 3) - 5) & 0x300) >> 8 | - (((mode->CrtcHDisplay >> 3) - 1) & 0x300) >> 6 | - ((mode->CrtcHBlankStart >> 3) & 0x300) >> 4 | - ((mode->CrtcHSyncStart >> 3) & 0x300) >> 2 ; - pReg->sisRegs3C4[0x0C] &= 0xF8; - pReg->sisRegs3C4[0x0C] |= - ((mode->CrtcHBlankEnd >> 3) & 0x0C0) >> 6 | - ((mode->CrtcHSyncEnd >> 3) & 0x020) >> 3; - - /* line compare */ - if (mode->CrtcHDisplay > 0) - pReg->sisRegs3C4[0x0F] |= 0x08; + /* Calculate Offset/Display Pitch */ + pSiS->scrnOffset = pSiS->CurrentLayout.displayWidth * + ((pSiS->CurrentLayout.bitsPerPixel + 7) / 8); + + pSiS->scrnPitch = pSiS->scrnPitch2 = pSiS->scrnOffset; + + if(realmode->Flags & V_INTERLACE) pSiS->scrnPitch <<= 1; + +#ifdef SISMERGED + if(pSiS->MergedFB) { + if(realmode2->Flags & V_INTERLACE) pSiS->scrnPitch2 <<= 1; + } else +#endif + pSiS->scrnPitch2 = pSiS->scrnPitch; + +#ifdef UNLOCK_ALWAYS + outSISIDXREG(SISSR, 0x05, 0x86); +#endif + + switch(pSiS->CurrentLayout.bitsPerPixel) { + case 8: + pSiS->DstColor = 0x0000; + pSiS->SiS310_AccelDepth = 0x00000000; + break; + case 16: + if(pSiS->CurrentLayout.depth == 15) + pSiS->DstColor = (short) 0x4000; else - pReg->sisRegs3C4[0x0F] &= 0xF7; - break; + pSiS->DstColor = (short) 0x8000; + pSiS->SiS310_AccelDepth = 0x00010000; + break; + case 24: + break; + case 32: + pSiS->DstColor = (short) 0xC000; + pSiS->SiS310_AccelDepth = 0x00020000; + break; } + /* Enable PCI LINEAR ADDRESSING (0x80), MMIO (0x01), PCI_IO (0x20) */ + pReg->sisRegs3C4[0x20] = 0xA1; - /* Set vclk */ - if (compute_vclk(clock, &num, &denum, &div, &sbit, &scale)) { - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - pReg->sisRegs3C4[XR2A] = (num - 1) & 0x7f ; - pReg->sisRegs3C4[XR2A] |= (div == 2) ? 0x80 : 0; - pReg->sisRegs3C4[XR2B] = ((denum -1) & 0x1f); - pReg->sisRegs3C4[XR2B] |= (((scale -1)&3) << 5); - /* When set VCLK, you should set SR13 first */ - if (sbit) - pReg->sisRegs3C4[ClockBase] |= 0x40; - else - pReg->sisRegs3C4[ClockBase] &= 0xBF; - - break; - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - pReg->sisRegs3C4[0x2B] = (num -1) & 0x7f; - if (div == 2) - pReg->sisRegs3C4[0x2B] |= 0x80; - pReg->sisRegs3C4[0x2C] = ((denum -1) & 0x1f); - pReg->sisRegs3C4[0x2C] |= (((scale-1)&3) << 5); - if (sbit) - pReg->sisRegs3C4[0x2C] |= 0x80; - pReg->sisRegs3C4[0x2D] = 0x80; - break; + /* Now initialize TurboQueue. TB is always located at the very top of + * the videoRAM (notably NOT the x framebuffer memory, which can/should + * be limited by MaxXFbMem when using DRI). Also, enable the accelerators. + */ + if (!pSiS->NoAccel) { + pReg->sisRegs3C4[0x1E] |= 0x42; /* Enable 2D accelerator */ + pReg->sisRegs3C4[0x1E] |= 0x18; /* Enable 3D accelerator */ + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + if(pSiS->TurboQueue) { /* set Turbo Queue as 512k */ + temp = ((pScrn->videoRam/64)-8); /* 8=512k, 4=256k, 2=128k, 1=64k */ + pReg->sisRegs3C4[0x26] = temp & 0xFF; + pReg->sisRegs3C4[0x27] = + (pReg->sisRegs3C4[0x27] & 0xfc) | (((temp >> 8) & 3) | 0xF0); + } /* line above new for saving D2&3 of status register */ + break; + case SIS_315_VGA: + /* See comments in sis_driver.c */ + pReg->sisRegs3C4[0x27] = 0x1F; + pReg->sisRegs3C4[0x26] = 0x22; + pReg->sisMMIO85C0 = (pScrn->videoRam - 512) * 1024; + break; } } - else { - /* if compute_vclk cannot handle the request clock try sisCalcClock! */ - SiSCalcClock(pScrn, clock, 2, vclk); - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - pReg->sisRegs3C4[XR2A] = (vclk[Midx] - 1) & 0x7f ; - pReg->sisRegs3C4[XR2A] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; - - /* bits [4:0] contain denumerator -MC */ - pReg->sisRegs3C4[XR2B] = (vclk[Nidx] -1) & 0x1f ; - - if (vclk[Pidx] <= 4){ - /* postscale 1,2,3,4 */ - pReg->sisRegs3C4[XR2B] |= (vclk[Pidx] -1 ) << 5 ; - pReg->sisRegs3C4[ClockBase] &= 0xBF; - } else { - /* postscale 6,8 */ - pReg->sisRegs3C4[XR2B] |= ((vclk[Pidx] / 2) -1 ) << 5 ; - pReg->sisRegs3C4[ClockBase] |= 0x40; - } - pReg->sisRegs3C4[XR2B] |= 0x80 ; /* gain for high frequency */ - break; - - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - pReg->sisRegs3C4[0x2B] = (vclk[Midx] - 1) & 0x7f ; - pReg->sisRegs3C4[0x2B] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; - - /* bits [4:0] contain denumerator -MC */ - pReg->sisRegs3C4[0x2C] = (vclk[Nidx] -1) & 0x1f ; - - if (vclk[Pidx] <= 4) { - /* postscale 1,2,3,4 */ - pReg->sisRegs3C4[0x2C] |= (vclk[Pidx] -1 ) << 5 ; - pReg->sisRegs3C4[0x2C] &= 0x7F; - } else { - /* postscale 6,8 */ - pReg->sisRegs3C4[0x2C] |= ((vclk[Pidx] / 2) -1 ) << 5 ; - pReg->sisRegs3C4[0x2C] |= 0x80; - } - pReg->sisRegs3C4[0x2D] = 0x80; - break; - } - } /* end of set vclk */ - - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - if (clock > 135000) pReg->sisRegs3C4[ClockReg] |= 0x02; - break; - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - if (clock > 150000) { /* enable two-pixel mode */ - pReg->sisRegs3C4[0x07] |= 0x80; - pReg->sisRegs3C4[0x32] |= 0x08; - } else { - pReg->sisRegs3C4[0x07] &= 0x7F; - pReg->sisRegs3C4[0x32] &= 0xF7; - } - pReg->sisRegs3C4[0x07] |= 0x10; - pReg->sisRegs3C4[0x07] &= 0xFC; - if (clock < 100000) - pReg->sisRegs3C4[0x07] |= 0x03; - else if (clock < 200000) - pReg->sisRegs3C4[0x07] |= 0x02; - else if (clock < 250000) - pReg->sisRegs3C4[0x07] |= 0x01; - break; - } - pReg->sisRegs3C2[0x00] = inb(0x3CC) | 0x0C; /* Programmable Clock */ + return(TRUE); +} - if (pSiS->FastVram && ((pSiS->Chipset == PCI_CHIP_SIS530) || - (pSiS->Chipset == PCI_CHIP_SIS6326) || - (pSiS->Chipset == PCI_CHIP_SIS5597))) - pReg->sisRegs3C4[ExtMiscCont5]|= 0xC0; - else - pReg->sisRegs3C4[ExtMiscCont5]&= ~0xC0; +int +SISDoSense(ScrnInfoPtr pScrn, int tempbl, int tempbh, int tempcl, int tempch) +{ + SISPtr pSiS = SISPTR(pScrn); + int temp; + + outSISIDXREG(SISPART4,0x11,tempbl); + temp = tempbh | tempcl; + setSISIDXREG(SISPART4,0x10,0xe0,temp); + SiS_DDC2Delay(pSiS->SiS_Pr, 0x1000); + tempch &= 0x7f; + inSISIDXREG(SISPART4,0x03,temp); + temp ^= 0x0e; + temp &= tempch; + return((temp == tempch)); +} - pSiS->ValidWidth = TRUE; - if ((pSiS->Chipset == PCI_CHIP_SIS5597) || - (pSiS->Chipset == PCI_CHIP_SIS6326) || - (pSiS->Chipset == PCI_CHIP_SIS530)) - { - pReg->sisRegs3C4[GraphEng] &= 0xCF; /* Clear logical width bits */ - if (pScrn->bitsPerPixel == 24) { - pReg->sisRegs3C4[GraphEng] |= 0x30; /* Invalid logical width */ - pSiS->ValidWidth = FALSE; +/* Sense connected devices on 30x */ +void SISSense30x(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char backupP4_0d,backupP2_00,biosflag; + unsigned char testsvhs_tempbl, testsvhs_tempbh; + unsigned char testsvhs_tempcl, testsvhs_tempch; + unsigned char testcvbs_tempbl, testcvbs_tempbh; + unsigned char testcvbs_tempcl, testcvbs_tempch; + unsigned char testvga2_tempbl, testvga2_tempbh; + unsigned char testvga2_tempcl, testvga2_tempch; + int myflag, result=0, i, j, haveresult; + unsigned short temp; + + inSISIDXREG(SISPART4,0x0d,backupP4_0d); + outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04)); + + inSISIDXREG(SISPART2,0x00,backupP2_00); + outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c)); + + SISDoSense(pScrn, 0, 0, 0, 0); + + if((pSiS->VGAEngine == SIS_315_VGA) || + (pSiS->Chipset == PCI_CHIP_SIS300)) { + if(pSiS->sishw_ext.UseROM) { + if(pSiS->VGAEngine == SIS_300_VGA) temp = 0xfe; + else { + temp = 0xf3; + if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { + temp = 0x11b; + } + } + if(pSiS->BIOS[temp] & 0x08) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS30x: Video bridge has DVI-I TMDS/VGA combo connector\n"); + orSISIDXREG(SISCR, 0x32, 0x80); + } else { + andSISIDXREG(SISCR, 0x32, 0x7f); + } + } + } + + if(pSiS->VGAEngine == SIS_300_VGA) { + + if(pSiS->sishw_ext.UseROM) { + testvga2_tempbh = pSiS->BIOS[0xf9]; testvga2_tempbl = pSiS->BIOS[0xf8]; + testsvhs_tempbh = pSiS->BIOS[0xfb]; testsvhs_tempbl = pSiS->BIOS[0xfa]; + testcvbs_tempbh = pSiS->BIOS[0xfd]; testcvbs_tempbl = pSiS->BIOS[0xfc]; + biosflag = pSiS->BIOS[0xfe]; + } else { + testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1; + testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9; + testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3; + biosflag = 0; } - else { - switch ( pScrn->virtualX * (pScrn->bitsPerPixel >> 3) ) { - case 1024: - pReg->sisRegs3C4[GraphEng] |= 0x00; /* | 00 = No change */ - break; - case 2048: - pReg->sisRegs3C4[GraphEng] |= 0x10; - break; - case 4096: - pReg->sisRegs3C4[GraphEng] |= 0x20; - break; - default: - /* Invalid logical width */ - pReg->sisRegs3C4[GraphEng] = 0x30; - pSiS->ValidWidth = FALSE; - break; - } + if(pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) { + testvga2_tempbh = 0x01; testvga2_tempbl = 0x90; + testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b; + testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74; + } + inSISIDXREG(SISPART4,0x01,myflag); + if(myflag & 0x04) { + testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd; + testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd; + testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee; + } + testvga2_tempch = 0x0e; testvga2_tempcl = 0x08; + testsvhs_tempch = 0x04; testsvhs_tempcl = 0x04; + testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04; + + if(pSiS->Chipset == PCI_CHIP_SIS300) { + inSISIDXREG(SISSR,0x3b,myflag); + if(!(myflag & 0x01)) { + testvga2_tempbh = 0x00; testvga2_tempbl = 0x00; + testvga2_tempch = 0x00; testvga2_tempcl = 0x00; + } } - } - PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "virtualX = %d depth = %d Logical width = %d\n", - pScrn->virtualX, pScrn->bitsPerPixel, - pScrn->virtualX * pScrn->bitsPerPixel/8)); - if (!pSiS->NoAccel) { - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - pReg->sisRegs3C4[GraphEng] |= 0x40; - if (pSiS->TurboQueue) { - pReg->sisRegs3C4[GraphEng] |= 0x80; - /* All Queue for 2D */ - pReg->sisRegs3C4[ExtMiscCont9] &= 0xFC; - if (pSiS->HWCursor) - pReg->sisRegs3C4[TurboQueueBase] = (pScrn->videoRam/32) - 2; - else - pReg->sisRegs3C4[TurboQueueBase] = (pScrn->videoRam/32) - 1; - } - pReg->sisRegs3C4[MMIOEnable] |= 0x60; /* At PCI base */ - pReg->sisRegs3C4[Mode64] |= 0x80; - break; - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - pReg->sisRegs3C4[0x1E] |= 0x40; - if (pSiS->TurboQueue) { /* set Turbo Queue as 512k */ - temp1 = ((pScrn->videoRam/64)-4); - pReg->sisRegs3C4[0x26] = temp1 & 0xFF; - pReg->sisRegs3C4[0x27] = ((temp1 >> 8) & 3) || 0xF0; - } - break; + } else { + + if(pSiS->sishw_ext.UseROM) { + if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { + testvga2_tempbh = pSiS->BIOS[0xe6]; testvga2_tempbl = pSiS->BIOS[0xe5]; + testsvhs_tempbh = pSiS->BIOS[0xe8]; testsvhs_tempbl = pSiS->BIOS[0xe7]; + testcvbs_tempbh = pSiS->BIOS[0xea]; testcvbs_tempbl = pSiS->BIOS[0xe9]; + biosflag = pSiS->BIOS[0x11b]; + } else { + testvga2_tempbh = pSiS->BIOS[0xbe]; testvga2_tempbl = pSiS->BIOS[0xbd]; + testsvhs_tempbh = pSiS->BIOS[0xc0]; testsvhs_tempbl = pSiS->BIOS[0xbf]; + testcvbs_tempbh = pSiS->BIOS[0xc2]; testcvbs_tempbl = pSiS->BIOS[0xc1]; + biosflag = pSiS->BIOS[0xf3]; + } + } else { + testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1; + testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9; + testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3; + biosflag = 0; } - } + + if(pSiS->VBFlags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) { + if(pSiS->sishw_ext.UseROM) { + if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { + testvga2_tempbh = pSiS->BIOS[0xec]; testvga2_tempbl = pSiS->BIOS[0xeb]; + testsvhs_tempbh = pSiS->BIOS[0xee]; testsvhs_tempbl = pSiS->BIOS[0xed]; + testcvbs_tempbh = pSiS->BIOS[0xf0]; testcvbs_tempbl = pSiS->BIOS[0xef]; + } else { + testvga2_tempbh = pSiS->BIOS[0xc4]; testvga2_tempbl = pSiS->BIOS[0xc3]; + testsvhs_tempbh = pSiS->BIOS[0xc6]; testsvhs_tempbl = pSiS->BIOS[0xc5]; + testcvbs_tempbh = pSiS->BIOS[0xc8]; testcvbs_tempbl = pSiS->BIOS[0xc7]; + } + } else { + if(pSiS->VBFlags & (VB_301B|VB_302B)) { + testvga2_tempbh = 0x01; testvga2_tempbl = 0x90; + testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b; + testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74; + } else { + testvga2_tempbh = 0x00; testvga2_tempbl = 0x00; + testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00; + testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00; + } + } + } + + if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B)) { + inSISIDXREG(SISPART4,0x01,myflag); + if(myflag & 0x04) { + testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd; + testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd; + testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee; + } + } + + if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { + /* TW: No VGA2 or SCART on LV bridges */ + testvga2_tempbh = 0x00; testvga2_tempbl = 0x00; + testvga2_tempch = 0x00; testvga2_tempcl = 0x00; + testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08; + testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08; + } else { + testvga2_tempch = 0x0e; testvga2_tempcl = 0x08; + testsvhs_tempch = 0x04; testsvhs_tempcl = 0x04; + testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04; + } + + } - /* Set memclock */ - if ((pSiS->Chipset == PCI_CHIP_SIS5597) || (pSiS->Chipset == PCI_CHIP_SIS6326)) { - if (pSiS->MemClock > 66000) { - SiSCalcClock(pScrn, pSiS->MemClock, 1, vclk); - - pReg->sisRegs3C4[MemClock0] = (vclk[Midx] - 1) & 0x7f ; - pReg->sisRegs3C4[MemClock0] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; - pReg->sisRegs3C4[MemClock1] = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */ - if (vclk[Pidx] <= 4){ - pReg->sisRegs3C4[MemClock1] |= (vclk[Pidx] -1 ) << 5 ; /* postscale 1,2,3,4 */ - pReg->sisRegs3C4[ClockBase] &= 0x7F; - } else { - pReg->sisRegs3C4[MemClock1] |= ((vclk[Pidx] / 2) -1 ) << 5 ; /* postscale 6,8 */ - pReg->sisRegs3C4[ClockBase] |= 0x80; - } - -#if 1 /* Check programmed memory clock. Enable only to check the above code */ - mclk=14318*((pReg->sisRegs3C4[MemClock0] & 0x7f)+1); - mclk=mclk/((pReg->sisRegs3C4[MemClock1] & 0x0f)+1); - Base = pReg->sisRegs3C4[ClockBase]; - if ( (Base & 0x80)==0 ) { - mclk = mclk / (((pReg->sisRegs3C4[MemClock1] & 0x60) >> 5)+1); - } else { - if ((pReg->sisRegs3C4[MemClock1] & 0x60) == 0x40) { mclk=mclk/6;} - if ((pReg->sisRegs3C4[MemClock1] & 0x60) == 0x60) { mclk=mclk/8;} + andSISIDXREG(SISCR, 0x32, ~0x14); + pSiS->postVBCR32 &= ~0x14; + if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) { +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiS30x: Scanning for VGA2/SCART (%x %x %x %x)\n", + testvga2_tempbh, testvga2_tempbl, testvga2_tempch, testvga2_tempcl); +#endif + + haveresult = 0; + for(j = 0; j < 10; j++) { + result = 0; + for(i = 0; i < 3; i++) { + if(SISDoSense(pScrn, testvga2_tempbl, testvga2_tempbh, + testvga2_tempcl, testvga2_tempch)) + result++; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,2, - "Setting memory clock to %.3f MHz\n", - mclk/1000.0); + if((result == 0) || (result >= 2)) break; + } + if(result) { + if(biosflag & 0x01) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS30x: Detected TV connected to SCART output\n"); + pSiS->VBFlags |= TV_SCART; + orSISIDXREG(SISCR, 0x32, 0x04); + pSiS->postVBCR32 |= 0x04; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS30x: Detected secondary VGA connection\n"); + pSiS->VBFlags |= VGA2_CONNECTED; + orSISIDXREG(SISCR, 0x32, 0x10); + pSiS->postVBCR32 |= 0x10; + } + } + if(biosflag & 0x01) pSiS->SiS_SD_Flags |= SiS_SD_VBHASSCART; + } + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiS30x: Scanning for TV (%x %x %x %x; %x %x %x %x)\n", + testsvhs_tempbh, testsvhs_tempbl, testsvhs_tempch, testsvhs_tempcl, + testcvbs_tempbh, testcvbs_tempbl, testcvbs_tempch, testcvbs_tempcl); #endif - } + + andSISIDXREG(SISCR, 0x32, ~0x03); + pSiS->postVBCR32 &= ~0x03; + + haveresult = 0; + for(j = 0; j < 10; j++) { + result = 0; + for(i = 0; i < 3; i++) { + if(SISDoSense(pScrn, testsvhs_tempbl, testsvhs_tempbh, + testsvhs_tempcl, testsvhs_tempch)) + result++; + } + if((result == 0) || (result >= 2)) break; + } + if(result) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS30x: Detected TV connected to SVIDEO output\n"); + pSiS->VBFlags |= TV_SVIDEO; + orSISIDXREG(SISCR, 0x32, 0x02); + pSiS->postVBCR32 |= 0x02; } - /* set threshold value */ - switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - MemBand = sisMemBandWidth(pScrn) / 10 ; - safetymargin = 1; - gap = 4; + if((biosflag & 0x02) || (!(result))) { - CRT_ENGthreshold = 0x0F; - CRT_CPUthresholdLow = ((pScrn->depth*clock) / MemBand)+safetymargin; - CRT_CPUthresholdHigh =((pScrn->depth*clock) / MemBand)+gap+safetymargin; + haveresult = 0; + for(j = 0; j < 10; j++) { + result = 0; + for(i = 0; i < 3; i++) { + if(SISDoSense(pScrn, testcvbs_tempbl, testcvbs_tempbh, + testcvbs_tempcl, testcvbs_tempch)) + result++; + } + if((result == 0) || (result >= 2)) break; + } + if(result) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS30x: Detected TV connected to COMPOSITE output\n"); + pSiS->VBFlags |= TV_AVIDEO; + orSISIDXREG(SISCR, 0x32, 0x01); + pSiS->postVBCR32 |= 0x01; + } + } - if ( CRT_CPUthresholdLow > (pScrn->depth < 24 ? 0xe:0x0d) ) { - CRT_CPUthresholdLow = (pScrn->depth < 24 ? 0xe:0x0d); - } + SISDoSense(pScrn, 0, 0, 0, 0); - if ( CRT_CPUthresholdHigh > (pScrn->depth < 24 ? 0x10:0x0f) ) { - CRT_CPUthresholdHigh = (pScrn->depth < 24 ? 0x10:0x0f); - } + outSISIDXREG(SISPART2,0x00,backupP2_00); + outSISIDXREG(SISPART4,0x0d,backupP4_0d); +} - pReg->sisRegs3C4[CPUThreshold] = (CRT_ENGthreshold & 0x0F) | - (CRT_CPUthresholdLow & 0x0F)<<4 ; - pReg->sisRegs3C4[CRTThreshold] = CRT_CPUthresholdHigh & 0x0F; - - break; - case PCI_CHIP_SIS530: - Find530Threshold(pScrn, pSiS->MemClock, mode->Clock, - pScrn->bitsPerPixel, pSiS->BusWidth, pSiS->Flags, - &CRT_CPUthresholdLow, &CRT_CPUthresholdHigh); - pReg->sisRegs3C4[8] = (CRT_CPUthresholdLow & 0xf) << 4 | 0xF; - pReg->sisRegs3C4[9] &= 0xF0; - pReg->sisRegs3C4[9] |= (CRT_CPUthresholdHigh & 0xF); - pReg->sisRegs3C4[0x3F] &= 0xE3; - pReg->sisRegs3C4[0x3F] |= (CRT_CPUthresholdHigh & 0x10) | - (CRT_CPUthresholdLow & 0x10) >> 2 | - 0x08; - break; - case PCI_CHIP_SIS300: - Find300_Threshold(pScrn, mode); - break; - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: /* temperary settings */ - Find630_Threshold(pScrn, mode); - break; +static void +SiS6326TVDelay(ScrnInfoPtr pScrn, int delay) +{ + SISPtr pSiS = SISPTR(pScrn); + int i; + unsigned char temp; + + for(i=0; i<delay; i++) { + inSISIDXREG(SISSR, 0x05, temp); } - outw(VGA_SEQ_INDEX, (SR5State << 8) | 0x05); /* Relock Registers */ - return(TRUE); } -/* - * Initialise a new mode. This is currently still using the old - * "initialise struct, restore/write struct to HW" model. That could - * be changed. - */ +int +SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl) +{ + unsigned char temp; + + SiS6326SetTVReg(pScrn, 0x42, tempbl); + temp = SiS6326GetTVReg(pScrn, 0x43); + temp &= 0xfc; + temp |= tempbh; + SiS6326SetTVReg(pScrn, 0x43, temp); + SiS6326TVDelay(pScrn, 0x1000); + temp = SiS6326GetTVReg(pScrn, 0x43); + temp |= 0x04; + SiS6326SetTVReg(pScrn, 0x43, temp); + SiS6326TVDelay(pScrn, 0x8000); + temp = SiS6326GetTVReg(pScrn, 0x44); + if(!(tempch & temp)) tempcl = 0; + return(tempcl); +} -static Bool -SiSModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +void +SISSense6326(ScrnInfoPtr pScrn) { - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaReg; SISPtr pSiS = SISPTR(pScrn); - SISRegPtr sisReg; - unsigned char temp; - - vgaHWUnlock(hwp); + unsigned char temp; + int result; + + pSiS->SiS6326Flags &= (SIS6326_HASTV | SIS6326_TVPAL); + temp = SiS6326GetTVReg(pScrn, 0x43); + temp &= 0xfb; + SiS6326SetTVReg(pScrn, 0x43, temp); + result = SIS6326DoSense(pScrn, 0x01, 0xb0, 0x06, SIS6326_TVSVIDEO); /* 0x02 */ + pSiS->SiS6326Flags |= result; + result = SIS6326DoSense(pScrn, 0x01, 0xa0, 0x01, SIS6326_TVCVBS); /* 0x04 */ + pSiS->SiS6326Flags |= result; + temp = SiS6326GetTVReg(pScrn, 0x43); + temp &= 0xfb; + SiS6326SetTVReg(pScrn, 0x43, temp); + if(pSiS->SiS6326Flags & (SIS6326_TVSVIDEO | SIS6326_TVCVBS)) { + pSiS->SiS6326Flags |= SIS6326_TVDETECTED; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS6326: Detected TV connected to %s output\n", + (((pSiS->SiS6326Flags & (SIS6326_TVSVIDEO | SIS6326_TVCVBS)) == + (SIS6326_TVSVIDEO | SIS6326_TVCVBS)) ? + "both SVIDEO and COMPOSITE" : + ((pSiS->SiS6326Flags & SIS6326_TVSVIDEO) ? + "SVIDEO" : "COMPOSITE"))); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS6326: No TV detected\n"); + } +} - SiSModifyModeInfo(mode); +/* TW: Detect video bridge and set VBFlags accordingly */ +void SISVGAPreInit(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + int temp,temp1,temp2, i; + int upperlimitlvds, lowerlimitlvds; + int upperlimitch, lowerlimitch; + int chronteltype, chrontelidreg; + unsigned char test[3]; +#if 0 + unsigned char sr17=0; +#endif + static const char *ChrontelTypeStr[] = { + "7004", + "7005", + "7007", + "7006", + "7008", + "7013", + "7019", + "7020", + "(unknown)" + }; + + switch (pSiS->Chipset) { + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS540: + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: + case PCI_CHIP_SIS315: + case PCI_CHIP_SIS315H: + case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: + pSiS->ModeInit = SIS300Init; + break; + default: + pSiS->ModeInit = SISInit; + } - /* Initialise the ModeReg values */ - if (!vgaHWInit(pScrn, mode)) - return FALSE; - pScrn->vtSema = TRUE; + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + unsigned char sr0d; + inSISIDXREG(SISSR, 0x0d, sr0d); + if(sr0d & 0x04) { + pSiS->SiS6326Flags |= SIS6326_TVPAL; + } + SISSense6326(pScrn); + } - setSISIDXREG(pSiS->RelIO+CROFFSET, 0x30, 0xFC, SWITCH_TO_CRT2); + pSiS->VBFlags = 0; /* reset VBFlags */ + pSiS->SiS_Pr->SiS_UseLCDA = FALSE; + pSiS->SiS_Pr->Backup = FALSE; + + /* TW: Videobridges only available for 300/315 series */ + if((pSiS->VGAEngine != SIS_300_VGA) && (pSiS->VGAEngine != SIS_315_VGA)) + return; + + inSISIDXREG(SISPART4, 0x00, temp); + temp &= 0x0F; + if (temp == 1) { + inSISIDXREG(SISPART4, 0x01, temp1); + temp1 &= 0xff; + if (temp1 >= 0xE0) { + pSiS->VBFlags |= VB_302LV; + pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS302LV video bridge (ID 1; Revision 0x%x)\n", + temp1); + } else if (temp1 >= 0xD0) { + pSiS->VBFlags |= VB_301LV; + pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS301LV video bridge (ID 1; Revision 0x%x)\n", + temp1); + } else if (temp1 >= 0xB0) { + pSiS->VBFlags |= VB_301B; + pSiS->sishw_ext.ujVBChipID = VB_CHIP_301B; + inSISIDXREG(SISPART4, 0x23, temp2); + if(!(temp2 & 0x02)) pSiS->VBFlags |= VB_30xBDH; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS301B%s video bridge (Revision 0x%x)\n", + (temp2 & 0x02) ? "" : " (DH)", + temp1); + } else { + pSiS->VBFlags |= VB_301; + pSiS->sishw_ext.ujVBChipID = VB_CHIP_301; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS301 video bridge (Revision 0x%x)\n", + temp1); + } - inSISIDXREG(pSiS->RelIO+CROFFSET, 0x31, temp); - temp &= 0xDD; - temp |= (DRIVER_MODE |DISABLE_CRT2_DISPLAY) >> 8; - outSISIDXREG(pSiS->RelIO+CROFFSET, 0x31, temp); + SISSense30x(pScrn); + + } else if (temp == 2) { + + inSISIDXREG(SISPART4, 0x01, temp1); + temp1 &= 0xff; + if (temp1 >= 0xE0) { + pSiS->VBFlags |= VB_302LV; + pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS302LV video bridge (ID 2; Revision 0x%x)\n", + temp1); + } else if (temp1 >= 0xD0) { + pSiS->VBFlags |= VB_301LV; + pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS301LV video bridge (ID 2; Revision 0x%x)\n", + temp1); + } else { + pSiS->VBFlags |= VB_302B; + pSiS->sishw_ext.ujVBChipID = VB_CHIP_302B; + inSISIDXREG(SISPART4, 0x23, temp2); + if(!(temp & 0x02)) pSiS->VBFlags |= VB_30xBDH; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS302B%s video bridge (Revision 0x%x)\n", + (temp2 & 0x02) ? "" : " (DH)", + temp1); + } - if (!SiSInit(pScrn, mode)) - return FALSE; + SISSense30x(pScrn); - PDEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "HDisplay: %d, VDisplay: %d \n", - mode->HDisplay, mode->VDisplay)); - /* Program the registers */ - vgaHWProtect(pScrn, TRUE); - vgaReg = &hwp->ModeReg; - sisReg = &pSiS->ModeReg; + } else if (temp == 3) { - vgaReg->Attribute[0x10] = 0x01; - if (pScrn->bitsPerPixel > 8) - vgaReg->Graphics[0x05] = 0x00; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS303 video bridge - not supported\n"); - vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + } else { - SiSRestore(pScrn, sisReg); + pSiS->sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN; + inSISIDXREG(SISCR, 0x37, temp); + temp = (temp >> 1) & 0x07; +#if 0 /* TW: This does not seem to be used on any machine */ + if ( (temp == 0) || (temp == 1)) { + pSiS->VBFlags |= VB_301; /* TW: 301 ? */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected SiS301 video bridge (Irregular bridge type %d)\n", temp); + } +#endif + if(pSiS->VGAEngine == SIS_300_VGA) { + lowerlimitlvds = 2; upperlimitlvds = 4; + lowerlimitch = 4; upperlimitch = 5; + chronteltype = 1; chrontelidreg = 0x25; + } else { + lowerlimitlvds = 2; upperlimitlvds = 3; + lowerlimitch = 3; upperlimitch = 3; + chronteltype = 2; chrontelidreg = 0x4b; + } - if (pSiS->VBFlags) { - SiSSetMode(pScrn, 0x44); - outSISIDXREG(pSiS->RelIO+CROFFSET, 0x32, - sisReg->sisRegs3C4[0x32]); + if((temp >= lowerlimitlvds) && (temp <= upperlimitlvds)) { + pSiS->VBFlags |= VB_LVDS; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected LVDS transmitter (Bridge type %d)\n", temp); + if(pSiS->Chipset == PCI_CHIP_SIS650) { + inSISIDXREG(SISCR, 0x38, temp1); + if(temp1 & 0x02) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "[LVDS: LCD channel A]\n"); + } + } } + if((temp >= lowerlimitch) && (temp <= upperlimitch)) { + /* TW: Set global for init301.c */ + pSiS->SiS_Pr->SiS_IF_DEF_CH70xx = chronteltype; - vgaHWProtect(pScrn, FALSE); + if(chronteltype == 1) { + /* Set general purpose IO for Chrontel communication */ + SiS_SetChrontelGPIO(pSiS->SiS_Pr, 0x9c); + } - if (pSiS->MemClock) - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, - "Memory clock is set to %3.3fMHz\n", pSiS->MemClock/1.0); + /* TW: Read Chrontel version number */ + temp1 = SiS_GetCH70xx(pSiS->SiS_Pr, chrontelidreg); + if(chronteltype == 1) { + /* TW: See Chrontel TB31 for explanation */ + temp2 = SiS_GetCH700x(pSiS->SiS_Pr, 0x0e); + if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) { + SiS_SetCH700x(pSiS->SiS_Pr, 0x0b0e); + SiS_DDC2Delay(pSiS->SiS_Pr, 300); + } + temp2 = SiS_GetCH70xx(pSiS->SiS_Pr, chrontelidreg); + if(temp2 != temp1) temp1 = temp2; + } + if(temp1 == 0xFFFF) { /* 0xFFFF = error reading DDC port */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Detected Chrontel 70xx, but encountered error reading I2C port\n"); + andSISIDXREG(SISCR, 0x32, ~0x07); + pSiS->postVBCR32 &= ~0x07; + } + /* TW: We only support device ids 0x19-200; other values may indicate DDC problems */ + else if((temp1 >= 0x19) && (temp1 <= 200)) { + pSiS->VBFlags |= VB_CHRONTEL; + switch (temp1) { + case 0x32: temp2 = 0; pSiS->ChrontelType = CHRONTEL_700x; break; + case 0x3A: temp2 = 1; pSiS->ChrontelType = CHRONTEL_700x; break; + case 0x50: temp2 = 2; pSiS->ChrontelType = CHRONTEL_700x; break; + case 0x2A: temp2 = 3; pSiS->ChrontelType = CHRONTEL_700x; break; + case 0x40: temp2 = 4; pSiS->ChrontelType = CHRONTEL_700x; break; + case 0x22: temp2 = 5; pSiS->ChrontelType = CHRONTEL_700x; break; + case 0x19: temp2 = 6; pSiS->ChrontelType = CHRONTEL_701x; break; + case 0x20: temp2 = 7; pSiS->ChrontelType = CHRONTEL_701x; break; /* ID for 7020? */ + default: temp2 = 8; pSiS->ChrontelType = CHRONTEL_701x; break; + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected Chrontel %s TV encoder (ID 0x%02x; bridge type %d)\n", + ChrontelTypeStr[temp2], temp1, temp); + + /* Sense connected TV's */ + + if(chronteltype == 1) { + + /* Chrontel 700x */ + + /* Read power status */ + temp1 = SiS_GetCH700x(pSiS->SiS_Pr, 0x0e); /* Power status */ + if((temp1 & 0x03) != 0x03) { + /* TW: Power all outputs */ + SiS_SetCH700x(pSiS->SiS_Pr, 0x0B0E); + SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); + } + /* Sense connected TV devices */ + for(i = 0; i < 3; i++) { + SiS_SetCH700x(pSiS->SiS_Pr, 0x0110); + SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); + SiS_SetCH700x(pSiS->SiS_Pr, 0x0010); + SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); + temp1 = SiS_GetCH700x(pSiS->SiS_Pr, 0x10); + if(!(temp1 & 0x08)) test[i] = 0x02; + else if(!(temp1 & 0x02)) test[i] = 0x01; + else test[i] = 0; + SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); + } + + if(test[0] == test[1]) temp1 = test[0]; + else if(test[0] == test[2]) temp1 = test[0]; + else if(test[1] == test[2]) temp1 = test[1]; + else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "TV detection unreliable - test results varied\n"); + temp1 = test[2]; + } -/* Reserved for debug - * - SiSIODump(pScrn); - SiSDumpModeInfo(pScrn, mode); - * - */ - return TRUE; -} + } else { -void SiSVGASetup(ScrnInfoPtr pScrn) -{ - SISPTR(pScrn)->ModeInit = SiSModeInit; + /* Chrontel 701x */ + + /* Backup Power register */ + temp1 = SiS_GetCH701x(pSiS->SiS_Pr, 0x49); + + /* Enable TV path */ + SiS_SetCH701x(pSiS->SiS_Pr, 0x2049); + + SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); + + /* Sense connected TV devices */ + temp2 = SiS_GetCH701x(pSiS->SiS_Pr, 0x20); + temp2 |= 0x01; + SiS_SetCH701x(pSiS->SiS_Pr, (temp2 << 8) | 0x20); + + SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); + + temp2 ^= 0x01; + SiS_SetCH701x(pSiS->SiS_Pr, (temp2 << 8) | 0x20); + + SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); + + temp2 = SiS_GetCH701x(pSiS->SiS_Pr, 0x20); + + /* Restore Power register */ + SiS_SetCH701x(pSiS->SiS_Pr, (temp1 << 8) | 0x49); + + temp1 = 0; + if(temp2 & 0x02) temp1 |= 0x01; + if(temp2 & 0x10) temp1 |= 0x01; + if(temp2 & 0x04) temp1 |= 0x02; + + if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04; + + } + + switch(temp1) { + case 0x01: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Chrontel: Detected TV connected to COMPOSITE output\n"); + pSiS->VBFlags |= TV_AVIDEO; + orSISIDXREG(SISCR, 0x32, 0x01); + andSISIDXREG(SISCR, 0x32, ~0x06); + pSiS->postVBCR32 |= 0x01; + pSiS->postVBCR32 &= ~0x06; + break; + case 0x02: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Chrontel: Detected TV connected to SVIDEO output\n"); + pSiS->VBFlags |= TV_SVIDEO; + orSISIDXREG(SISCR, 0x32, 0x02); + andSISIDXREG(SISCR, 0x32, ~0x05); + pSiS->postVBCR32 |= 0x02; + pSiS->postVBCR32 &= ~0x05; + break; + case 0x04: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Chrontel: Detected TV connected to SCART output or 480i HDTV\n"); + if(pSiS->chtvtype == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Chrontel: Use CHTVType option to select either SCART or HDTV\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Chrontel: Using SCART by default\n"); + pSiS->chtvtype = 1; + } + if(pSiS->chtvtype) + pSiS->VBFlags |= TV_CHSCART; + else + pSiS->VBFlags |= TV_CHHDTV; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Chrontel: No TV detected.\n"); + andSISIDXREG(SISCR, 0x32, ~0x07); + pSiS->postVBCR32 &= ~0x07; + } + + } else if(temp1==0) { + /* This indicates a communication problem, but it only occures if there + * is no TV attached. So we don't use TV in this case. + */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Detected Chrontel TV encoder in promiscuous state (DDC/I2C mix-up)\n"); + andSISIDXREG(SISCR, 0x32, ~0x07); + pSiS->postVBCR32 &= ~0x07; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chrontel: Unsupported device id (%d) detected\n",temp1); + andSISIDXREG(SISCR, 0x32, ~0x07); + pSiS->postVBCR32 &= ~0x07; + } + if(chronteltype == 1) { + /* Set general purpose IO for Chrontel communication */ + SiS_SetChrontelGPIO(pSiS->SiS_Pr, 0x00); + } + } + if ((pSiS->VGAEngine == SIS_300_VGA) && (temp == 3)) { + pSiS->VBFlags |= VB_TRUMPION; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected Trumpion Zurac (I/II/III) LVDS scaler\n"); + } + if (temp > upperlimitlvds) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Detected unknown bridge type (%d)\n", temp); + } + } + + /* Old BIOSes store the detected CRT2 type in SR17, 16 and 13 + * instead of CR32. However, since our detection routines + * store their results to CR32, we now copy the + * remaining bits (for LCD and VGA) to CR32 for unified usage. + * SR17[0] CRT1 [1] LCD [2] TV [3] VGA2 + * [4] AVIDEO [5] SVIDEO + * SR13[0] SCART [1] HiVision + * SR16[5] PAL/NTSC [6] LCD-SCALE [7] OVERSCAN + */ + +#if 0 + inSISIDXREG(SISSR, 0x17, sr17); + if( (pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->Chipset != PCI_CHIP_SIS300) && + (sr17 & 0x0F) ) { + + unsigned char cr32; + inSISIDXREG(SISCR, 0x32, cr32); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Converting SR17 (%02x) to CR32 (%02x)\n", sr17, cr32); + + if(sr17 & 0x01) { /* CRT1 */ + orSISIDXREG(SISCR, 0x32, 0x20); + pSiS->postVBCR32 |= 0x20; + } else { + andSISIDXREG(SISCR, 0x32, ~0x20); + pSiS->postVBCR32 &= ~0x20; + } + + if(sr17 & 0x02) { /* LCD */ + orSISIDXREG(SISCR, 0x32, 0x08); + pSiS->postVBCR32 |= 0x08; + } else { + andSISIDXREG(SISCR, 0x32, ~0x08); + pSiS->postVBCR32 &= ~0x08; + } + + /* No Hivision, no DVI here */ + andSISIDXREG(SISCR,0x32,~0xc0); + pSiS->postVBCR32 &= ~0xc0; + } +#endif + + /* Try to find out if the bridge uses LCDA for low resolution and + * text modes. If sisfb saved this for us, use it. Otherwise, + * check if we are running on a low mode on LCD and read the + * relevant registers ourselves. + */ + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & (VB_302B | VB_301LV | VB_302LV)) { + if(pSiS->sisfblcda != 0xff) { + if((pSiS->sisfblcda & 0x03) == 0x03) { + pSiS->SiS_Pr->SiS_UseLCDA = TRUE; + pSiS->VBFlags |= VB_USELCDA; + } + } else { + inSISIDXREG(SISCR,0x34,temp); + if(temp <= 0x13) { + inSISIDXREG(SISCR,0x38,temp); + if((temp & 0x03) == 0x03) { + pSiS->SiS_Pr->SiS_UseLCDA = TRUE; + pSiS->VBFlags |= VB_USELCDA; + pSiS->SiS_Pr->Backup = TRUE; + } else { + inSISIDXREG(SISCR,0x35,temp); + if(temp & 0x01) { + pSiS->SiS_Pr->SiS_UseLCDA = TRUE; + pSiS->VBFlags |= VB_USELCDA; + pSiS->SiS_Pr->Backup = TRUE; + } else { + inSISIDXREG(SISCR,0x30,temp); + if(temp & 0x20) { + orSISIDXREG(SISPART1,0x2f,0x01); /* Unlock CRT2 */ + inSISIDXREG(SISPART1,0x13,temp); + if(temp & 0x04) { + pSiS->SiS_Pr->SiS_UseLCDA = TRUE; + pSiS->VBFlags |= VB_USELCDA; + pSiS->SiS_Pr->Backup = TRUE; + } + } + } + } + } + } + if(pSiS->VBFlags & VB_USELCDA) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bridge uses LCDA for low resolution and text modes\n"); + if(pSiS->SiS_Pr->Backup == TRUE) { + inSISIDXREG(SISCR,0x34,pSiS->SiS_Pr->Backup_Mode); + inSISIDXREG(SISPART1,0x14,pSiS->SiS_Pr->Backup_14); + inSISIDXREG(SISPART1,0x15,pSiS->SiS_Pr->Backup_15); + inSISIDXREG(SISPART1,0x16,pSiS->SiS_Pr->Backup_16); + inSISIDXREG(SISPART1,0x17,pSiS->SiS_Pr->Backup_17); + inSISIDXREG(SISPART1,0x18,pSiS->SiS_Pr->Backup_18); + inSISIDXREG(SISPART1,0x19,pSiS->SiS_Pr->Backup_19); + inSISIDXREG(SISPART1,0x1a,pSiS->SiS_Pr->Backup_1a); + inSISIDXREG(SISPART1,0x1b,pSiS->SiS_Pr->Backup_1b); + inSISIDXREG(SISPART1,0x1c,pSiS->SiS_Pr->Backup_1c); + inSISIDXREG(SISPART1,0x1d,pSiS->SiS_Pr->Backup_1d); + } + } + } + } } + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c index 9c91fd320..7a731e9d3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c @@ -1,40 +1,84 @@ -/*************************************************************************** - -Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c,v 1.1 2000/12/02 01:16:19 dawes Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c,v 1.23 2003/08/10 21:25:38 twini Exp $ */ /* - * sis_video.c: SIS Xv driver. Based on the mga Xv driver by Mark Vojkovich - * and i810 Xv driver by Jonathan Bian <jonathan.bian@intel.com>. + * Xv driver for SiS 300, 315 and 330 series. + * + * Copyright 2002,2003 by Thomas Winischhofer, Vienna, Austria. + * All Rights Reserved. + * + * Formerly and in basic structure based on the mga Xv driver by Mark Vojkovich + * and i810 Xv driver by Jonathan Bian <jonathan.bian@intel.com>. + * + * Formerly based on a mostly non-working fragment for the 630 by + * Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * - * Authors: - * Sung-Ching Lin <sclin@sis.com.tw> + * Authors: + * Thomas Winischhofer <thomas@winischhofer.net>: + * (Original code fragment for 630 by + * Sung-Ching Lin <sclin@sis.com.tw>) * - * Notes: * + * All comments in this file are by Thomas Winischhofer. + * + * This supports the following chipsets: + * SiS300: No registers >0x65, two overlays (one used for CRT1, one for CRT2) + * SiS630/730: No registers >0x6b, two overlays (one used for CRT1, one for CRT2) + * SiS550: Full register range, two overlays (one used for CRT1, one for CRT2) + * SiS315: Full register range, one overlay (used for both CRT1 and CRT2 alt.) + * SiS650/740: Full register range, one overlay (used for both CRT1 and CRT2 alt.) + * SiSM650/651: Full register range, two overlays (one used for CRT1, one for CRT2) + * SiS330: Full register range, one overlay (used for both CRT1 and CRT2 alt.) + * SiS660: Full register range, two overlays (one used for CRT1, one for CRT2) + * + * Help for reading the code: + * 315/550/650/740/M650/651/330/660 = SIS_315_VGA + * 300/630/730 = SIS_300_VGA + * For chipsets with 2 overlays, hasTwoOverlays will be true + * + * Notes on display modes: + * + * -) dual head mode: + * DISPMODE is either SINGLE1 or SINGLE2, hence you need to check dualHeadMode flag + * DISPMODE is _never_ MIRROR. + * a) Chipsets with 2 overlays: + * 315/330 series: Only half sized overlays available (width 960) + * Overlay 1 is used on CRT1, overlay 2 for CRT2. + * b) Chipsets with 1 overlay: + * Full size overlays available. + * Overlay is used for either CRT1 or CRT2 + * -) merged fb mode: + * a) Chipsets with 2 overlays: + * 315/330 series: Only half sized overlays available (width 960) + * DISPMODE is always MIRROR. Overlay 1 is used for CRT1, overlay 2 for CRT2. + * b) Chipsets with 1 overlay: + * Full size overlays available. + * DISPMODE is either SINGLE1 or SINGLE2. Overlay is used accordingly on either + * CRT1 or CRT2 (automatically, where it is located) + * -) mirror mode (without dualhead or mergedfb) + * a) Chipsets with 2 overlays: + * 315/330 series: Only half sized overlays available (width 960) + * DISPMODE is MIRROR. Overlay 1 is used for CRT1, overlay 2 for CRT2. + * b) Chipsets with 1 overlay: + * Full size overlays available. + * DISPMODE is either SINGLE1 or SINGLE2. Overlay is used depending on + * XvOnCRT2 flag. */ #include "xf86.h" @@ -53,158 +97,162 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xaa.h" #include "xaalocal.h" #include "dixstruct.h" - -/* TODO: move to sis_regs.h */ -#include "sis_vidregs.h" - -#define OFF_DELAY 200 /* milliseconds */ -#define FREE_DELAY 60000 - -#define OFF_TIMER 0x01 -#define FREE_TIMER 0x02 -#define CLIENT_VIDEO_ON 0x04 +#include "fourcc.h" + +#include "sis_regs.h" + +static XF86VideoAdaptorPtr SISSetupImageVideo(ScreenPtr); +static void SISStopVideo(ScrnInfoPtr, pointer, Bool); +static int SISSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int SISGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); +static void SISQueryBestSize(ScrnInfoPtr, Bool, short, short, short, + short, unsigned int *,unsigned int *, pointer); +static int SISPutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int SISQueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); +static void SISVideoTimerCallback(ScrnInfoPtr pScrn, Time now); +static void SISInitOffscreenImages(ScreenPtr pScrn); +extern BOOLEAN SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn); + +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 #define TIMER_MASK (OFF_TIMER | FREE_TIMER) -static XF86VideoAdaptorPtr SISSetupImageVideo(ScreenPtr); -static void SISStopVideo(ScrnInfoPtr, pointer, Bool); -static int SISSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); -static int SISGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); -static void SISQueryBestSize(ScrnInfoPtr, Bool, - short, short, short, short, unsigned int *, unsigned int *, pointer); -static int SISPutImage( ScrnInfoPtr, - short, short, short, short, short, short, short, short, - int, unsigned char*, short, short, Bool, RegionPtr, pointer); -static int SISQueryImageAttributes(ScrnInfoPtr, - int, unsigned short *, unsigned short *, int *, int *); - -static void SISBlockHandler(int, pointer, pointer, pointer); +#define WATCHDOG_DELAY 500000 /* Watchdog counter for Vertical Restrace waiting */ #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) -static Atom xvBrightness, xvContrast, xvColorKey; +#define IMAGE_MIN_WIDTH 32 /* Minimum and maximum source image sizes */ +#define IMAGE_MIN_HEIGHT 24 +#define IMAGE_MAX_WIDTH_300 720 +#define IMAGE_MAX_HEIGHT_300 576 +#define IMAGE_MAX_WIDTH_315 1920 +#define IMAGE_MAX_HEIGHT_315 1080 -#define IMAGE_MIN_WIDTH 32 -#define IMAGE_MIN_HEIGHT 24 -#define IMAGE_MAX_WIDTH 720 -#define IMAGE_MAX_HEIGHT 576 +#define OVERLAY_MIN_WIDTH 32 /* Minimum overlay sizes */ +#define OVERLAY_MIN_HEIGHT 24 -#define DISPMODE_SINGLE1 0x1 -#define DISPMODE_SINGLE2 0x2 -#define DISPMODE_MIRROR 0x4 +#define DISPMODE_SINGLE1 0x1 /* CRT1 only */ +#define DISPMODE_SINGLE2 0x2 /* CRT2 only */ +#define DISPMODE_MIRROR 0x4 /* CRT1 + CRT2 MIRROR (see note below) */ -/**************************************************************************** -* raw register access : these routines directly interact with the sis's -* control aperature. must not be called until after -* the board's pci memory has been mapped. -****************************************************************************/ +#define LINEBUFLIMIT1 384 /* Limits at which line buffers must be merged */ +#define LINEBUFLIMIT2 720 -static CARD32 _sisread(SISPtr pSIS, CARD32 reg) -{ - return *(pSIS->IOBase + reg); -} +#ifdef SISDUALHEAD +#define HEADOFFSET (pSiS->dhmOffset) +#endif -static void _siswrite(SISPtr pSIS, CARD32 reg, CARD32 data) -{ - *(pSIS->IOBase + reg) = data; -} +/* TW: Note on "MIRROR": + * When using VESA on machines with an enabled video bridge, this means + * a real mirror. CRT1 and CRT2 have the exact same resolution and + * refresh rate. The same applies to modes which require the bridge to + * operate in slave mode. + * When not using VESA and the bridge is not in slave mode otherwise, + * CRT1 and CRT2 have the same resolution but possibly a different + * refresh rate. + */ -static CARD8 getvideoreg(SISPtr pSIS, CARD8 reg) -{ - outb (pSIS->RelIO + vi_index_offset, reg); - return inb(pSIS->RelIO + vi_data_offset); -} +/**************************************************************************** + * Raw register access : These routines directly interact with the sis's + * control aperature. Must not be called until after + * the board's pci memory has been mapped. + ****************************************************************************/ -static void setvideoreg(SISPtr pSIS, CARD8 reg, CARD8 data) +#if 0 +static CARD32 _sisread(SISPtr pSiS, CARD32 reg) { - outb (pSIS->RelIO + vi_index_offset, reg); - outb (pSIS->RelIO + vi_data_offset, data); + return *(pSiS->IOBase + reg); } -static void setvideoregmask(SISPtr pSIS, CARD8 reg, CARD8 data, CARD8 mask) +static void _siswrite(SISPtr pSiS, CARD32 reg, CARD32 data) { - CARD8 old; - - outb (pSIS->RelIO + vi_index_offset, reg); - old = inb(pSIS->RelIO + vi_data_offset); - data = (data & mask) | (old & (~mask)); - outb (pSIS->RelIO + vi_data_offset, data); + *(pSiS->IOBase + reg) = data; } +#endif -static CARD8 getsrreg(SISPtr pSIS, CARD8 reg) +static CARD8 getsrreg(SISPtr pSiS, CARD8 reg) { - outb (pSIS->RelIO + sr_index_offset, 0x05); - if (inb (pSIS->RelIO + sr_data_offset) != 0xa1) - outb (pSIS->RelIO + sr_data_offset, 0x86); - outb (pSIS->RelIO + sr_index_offset, reg); - return inb(pSIS->RelIO + sr_data_offset); + CARD8 ret; + inSISIDXREG(SISSR, reg, ret); + return(ret); } -static void setsrreg(SISPtr pSIS, CARD8 reg, CARD8 data) +static CARD8 getvideoreg(SISPtr pSiS, CARD8 reg) { - outb (pSIS->RelIO + sr_index_offset, 0x05); - if (inb (pSIS->RelIO + sr_data_offset) != 0xa1) - outb (pSIS->RelIO + sr_data_offset, 0x86); - outb (pSIS->RelIO + sr_index_offset, reg); - outb (pSIS->RelIO + sr_data_offset, data); + CARD8 ret; + inSISIDXREG(SISVID, reg, ret); + return(ret); } -static void setsrregmask(SISPtr pSIS, CARD8 reg, CARD8 data, CARD8 mask) +static __inline void setvideoreg(SISPtr pSiS, CARD8 reg, CARD8 data) { - CARD8 old; - - outb (pSIS->RelIO + sr_index_offset, 0x05); - if (inb (pSIS->RelIO + sr_data_offset) != 0xa1) - outb (pSIS->RelIO + sr_data_offset, 0x86); - outb (pSIS->RelIO + sr_index_offset, reg); - old = inb(pSIS->RelIO + sr_data_offset); - data = (data & mask) | (old & (~mask)); - outb (pSIS->RelIO + sr_data_offset, data); + outSISIDXREG(SISVID, reg, data); } -static CARD8 getsisreg(SISPtr pSIS, CARD8 index_offset, CARD8 reg) +static __inline void setvideoregmask(SISPtr pSiS, CARD8 reg, CARD8 data, CARD8 mask) { - outb (pSIS->RelIO + index_offset, reg); - return inb(pSIS->RelIO + index_offset+1); + CARD8 old; + inSISIDXREG(SISVID, reg, old); + data = (data & mask) | (old & (~mask)); + outSISIDXREG(SISVID, reg, data); } -static void setsisreg(SISPtr pSIS, CARD8 index_offset, CARD8 reg, CARD8 data) +static void setsrregmask(SISPtr pSiS, CARD8 reg, CARD8 data, CARD8 mask) { - outb (pSIS->RelIO + index_offset, reg); - outb (pSIS->RelIO + index_offset+1, data); + CARD8 old; + + inSISIDXREG(SISSR, reg, old); + data = (data & mask) | (old & (~mask)); + outSISIDXREG(SISSR, reg, data); } /* VBlank */ -static CARD8 vblank_active_CRT1(SISPtr pSIS) +static CARD8 vblank_active_CRT1(SISPtr pSiS) { - return (inb(pSIS->RelIO + input_stat) & 0x08); + return (inSISREG(SISINPSTAT) & 0x08); } -static CARD8 vblank_active_CRT2(SISPtr pSIS) +static CARD8 vblank_active_CRT2(SISPtr pSiS) { - return (getsisreg(pSIS, crt2_index_offset, Index_CRT2_FC_VR) & 0x02); + CARD8 ret; + if(pSiS->VGAEngine == SIS_315_VGA) { + inSISIDXREG(SISPART1, Index_310_CRT2_FC_VR, ret); + } else { + inSISIDXREG(SISPART1, Index_CRT2_FC_VR, ret); + } + return((ret & 0x02) ^ 0x02); } -/* Scanline */ -static CARD32 get_scanline_CRT1(SISPtr pSIS) +/* Scanline - unused */ +#if 0 +static CARD32 get_scanline_CRT1(SISPtr pSiS) { - CARD32 line; + CARD32 line; - _siswrite (pSIS, REG_PRIM_CRT_COUNTER, 0x00000001); - line = _sisread (pSIS, REG_PRIM_CRT_COUNTER); + _siswrite (pSiS, REG_PRIM_CRT_COUNTER, 0x00000001); + line = _sisread (pSiS, REG_PRIM_CRT_COUNTER); - return ((line >> 16) & 0x07FF); + return ((line >> 16) & 0x07FF); } -static CARD32 get_scanline_CRT2(SISPtr pSIS) +static CARD32 get_scanline_CRT2(SISPtr pSiS) { - CARD32 line; + CARD32 line; - line = (CARD32)(getsisreg(pSIS, crt2_index_offset, Index_CRT2_FC_VCount1) & 0x70) * 16 - + getsisreg(pSIS, crt2_index_offset, Index_CRT2_FC_VCount); + line = (CARD32)(getsisreg(pSiS, SISPART1, Index_CRT2_FC_VCount1) & 0x70) * 16 + + getsisreg(pSiS, SISPART1, Index_CRT2_FC_VCount); - return line; + return line; } +#endif void SISInitVideo(ScreenPtr pScreen) { @@ -212,259 +260,911 @@ void SISInitVideo(ScreenPtr pScreen) XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; XF86VideoAdaptorPtr newAdaptor = NULL; int num_adaptors; - - if (pScrn->bitsPerPixel != 8) - { - newAdaptor = SISSetupImageVideo(pScreen); - } + + newAdaptor = SISSetupImageVideo(pScreen); + if(newAdaptor) + SISInitOffscreenImages(pScreen); num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); if(newAdaptor) { - if(!num_adaptors) { - num_adaptors = 1; - adaptors = &newAdaptor; - } else { - newAdaptors = /* need to free this someplace */ - xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); - if(newAdaptors) { - memcpy(newAdaptors, adaptors, num_adaptors * - sizeof(XF86VideoAdaptorPtr)); - newAdaptors[num_adaptors] = newAdaptor; - adaptors = newAdaptors; - num_adaptors++; - } - } + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + /* need to free this someplace */ + newAdaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } } if(num_adaptors) xf86XVScreenInit(pScreen, adaptors, num_adaptors); if(newAdaptors) - xfree(newAdaptors); + xfree(newAdaptors); } - /* client libraries expect an encoding */ -static XF86VideoEncodingRec DummyEncoding[1] = +static XF86VideoEncodingRec DummyEncoding = { - { 0, "XV_IMAGE", - IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + 0, 0, /* Will be filled in */ {1, 1} - } }; -#define NUM_FORMATS 2 +#define NUM_FORMATS 3 -static XF86VideoFormatRec Formats[NUM_FORMATS] = +static XF86VideoFormatRec SISFormats[NUM_FORMATS] = { - {16, TrueColor}, {24, TrueColor} + { 8, PseudoColor}, + {16, TrueColor}, + {24, TrueColor} }; -#define NUM_ATTRIBUTES 3 +static char sisxvcolorkey[] = "XV_COLORKEY"; +static char sisxvbrightness[] = "XV_BRIGHTNESS"; +static char sisxvcontrast[] = "XV_CONTRAST"; +static char sisxvsaturation[] = "XV_SATURATION"; +static char sisxvhue[] = "XV_HUE"; +static char sisxvautopaintcolorkey[] = "XV_AUTOPAINT_COLORKEY"; +static char sisxvsetdefaults[] = "XV_SET_DEFAULTS"; +static char sisxvswitchcrt[] = "XV_SWITCHCRT"; +static char sisxvtvxposition[] = "XV_TVXPOSITION"; +static char sisxvtvyposition[] = "XV_TVYPOSITION"; +static char sisxvdisablegfx[] = "XV_DISABLE_GRAPHICS"; +static char sisxvdisablegfxlr[] = "XV_DISABLE_GRAPHICS_LR"; +static char sisxvdisablecolorkey[] = "XV_DISABLE_COLORKEY"; +static char sisxvusechromakey[] = "XV_USE_CHROMAKEY"; +static char sisxvinsidechromakey[] = "XV_INSIDE_CHROMAKEY"; +static char sisxvyuvchromakey[] = "XV_YUV_CHROMAKEY"; +static char sisxvchromamin[] = "XV_CHROMAMIN"; +static char sisxvchromamax[] = "XV_CHROMAMAX"; +static char sisxvqueryvbflags[] = "XV_QUERYVBFLAGS"; +static char sisxvsdgetdriverversion[] = "XV_SD_GETDRIVERVERSION"; +static char sisxvsdgethardwareinfo[] = "XV_SD_GETHARDWAREINFO"; +static char sisxvsdgetbusid[] = "XV_SD_GETBUSID"; +static char sisxvsdqueryvbflagsversion[] = "XV_SD_QUERYVBFLAGSVERSION"; +static char sisxvsdgetsdflags[] = "XV_SD_GETSDFLAGS"; +static char sisxvsdunlocksisdirect[] = "XV_SD_UNLOCKSISDIRECT"; +static char sisxvsdsetvbflags[] = "XV_SD_SETVBFLAGS"; +static char sisxvsdquerydetecteddevices[] = "XV_SD_QUERYDETECTEDDEVICES"; +static char sisxvsdcrt1status[] = "XV_SD_CRT1STATUS"; +static char sisxvsdcheckmodeindexforcrt2[] = "XV_SD_CHECKMODEINDEXFORCRT2"; +static char sisxvsdresultcheckmodeindexforcrt2[] = "XV_SD_RESULTCHECKMODEINDEXFORCRT2"; +static char sisxvsdsisantiflicker[] = "XV_SD_SISANTIFLICKER"; +static char sisxvsdsissaturation[] = "XV_SD_SISSATURATION"; +static char sisxvsdsisedgeenhance[] = "XV_SD_SISEDGEENHANCE"; +static char sisxvsdsiscolcalibf[] = "XV_SD_SISCOLCALIBF"; +static char sisxvsdsiscolcalibc[] = "XV_SD_SISCOLCALIBC"; +static char sisxvsdsiscfilter[] = "XV_SD_SISCFILTER"; +static char sisxvsdsisyfilter[] = "XV_SD_SISYFILTER"; +static char sisxvsdchcontrast[] = "XV_SD_CHCONTRAST"; +static char sisxvsdchtextenhance[] = "XV_SD_CHTEXTENHANCE"; +static char sisxvsdchchromaflickerfilter[] = "XV_SD_CHCHROMAFLICKERFILTER"; +static char sisxvsdchlumaflickerfilter[] = "XV_SD_CHLUMAFLICKERFILTER"; +static char sisxvsdchcvbscolor[] = "XV_SD_CHCVBSCOLOR"; +static char sisxvsdchoverscan[] = "XV_SD_CHOVERSCAN"; +static char sisxvsdenablegamma[] = "XV_SD_ENABLEGAMMA"; +static char sisxvsdtvxscale[] = "XV_SD_TVXSCALE"; +static char sisxvsdtvyscale[] = "XV_SD_TVYSCALE"; +static char sisxvsdgetscreensize[] = "XV_SD_GETSCREENSIZE"; +static char sisxvsdstorebrir[] = "XV_SD_STOREDGAMMABRIR"; +static char sisxvsdstorebrig[] = "XV_SD_STOREDGAMMABRIG"; +static char sisxvsdstorebrib[] = "XV_SD_STOREDGAMMABRIB"; +static char sisxvsdstorepbrir[] = "XV_SD_STOREDGAMMAPBRIR"; +static char sisxvsdstorepbrig[] = "XV_SD_STOREDGAMMAPBRIG"; +static char sisxvsdstorepbrib[] = "XV_SD_STOREDGAMMAPBRIB"; + +#ifndef SIS_CP +#define NUM_ATTRIBUTES_300 50 +#define NUM_ATTRIBUTES_315 52 +#endif + +static XF86AttributeRec SISAttributes_300[NUM_ATTRIBUTES_300] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvcolorkey}, + {XvSettable | XvGettable, -128, 127, sisxvbrightness}, + {XvSettable | XvGettable, 0, 7, sisxvcontrast}, + {XvSettable | XvGettable, 0, 1, sisxvautopaintcolorkey}, + {XvSettable , 0, 0, sisxvsetdefaults}, + {XvSettable | XvGettable, -32, 32, sisxvtvxposition}, + {XvSettable | XvGettable, -32, 32, sisxvtvyposition}, + {XvSettable | XvGettable, 0, 1, sisxvdisablegfx}, + {XvSettable | XvGettable, 0, 1, sisxvdisablegfxlr}, + {XvSettable | XvGettable, 0, 1, sisxvdisablecolorkey}, + {XvSettable | XvGettable, 0, 1, sisxvusechromakey}, + {XvSettable | XvGettable, 0, 1, sisxvinsidechromakey}, + {XvSettable | XvGettable, 0, 1, sisxvyuvchromakey}, + {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvchromamin}, + {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvchromamax}, + { XvGettable, 0, 0xffffffff, sisxvqueryvbflags}, + { XvGettable, 0, 0xffffffff, sisxvsdgetdriverversion}, + { XvGettable, 0, 0xffffffff, sisxvsdgethardwareinfo}, + { XvGettable, 0, 0xffffffff, sisxvsdgetbusid}, + { XvGettable, 0, 0xffffffff, sisxvsdqueryvbflagsversion}, + { XvGettable, 0, 0xffffffff, sisxvsdgetsdflags}, + {XvSettable | XvGettable, 0, 0xffffffff, sisxvsdunlocksisdirect}, + {XvSettable , 0, 0xffffffff, sisxvsdsetvbflags}, + { XvGettable, 0, 0xffffffff, sisxvsdquerydetecteddevices}, + {XvSettable | XvGettable, 0, 1, sisxvsdcrt1status}, + {XvSettable , 0, 0xffffffff, sisxvsdcheckmodeindexforcrt2}, + { XvGettable, 0, 0xffffffff, sisxvsdresultcheckmodeindexforcrt2}, + {XvSettable | XvGettable, 0, 4, sisxvsdsisantiflicker}, + {XvSettable | XvGettable, 0, 15, sisxvsdsissaturation}, + {XvSettable | XvGettable, 0, 15, sisxvsdsisedgeenhance}, + {XvSettable | XvGettable, -128, 127, sisxvsdsiscolcalibf}, + {XvSettable | XvGettable, -120, 120, sisxvsdsiscolcalibc}, + {XvSettable | XvGettable, 0, 1, sisxvsdsiscfilter}, + {XvSettable | XvGettable, 0, 8, sisxvsdsisyfilter}, + {XvSettable | XvGettable, 0, 15, sisxvsdchcontrast}, + {XvSettable | XvGettable, 0, 15, sisxvsdchtextenhance}, + {XvSettable | XvGettable, 0, 15, sisxvsdchchromaflickerfilter}, + {XvSettable | XvGettable, 0, 15, sisxvsdchlumaflickerfilter}, + {XvSettable | XvGettable, 0, 1, sisxvsdchcvbscolor}, + {XvSettable | XvGettable, 0, 3, sisxvsdchoverscan}, + {XvSettable | XvGettable, 0, 3, sisxvsdenablegamma}, + {XvSettable | XvGettable, -16, 16, sisxvsdtvxscale}, + {XvSettable | XvGettable, -4, 3, sisxvsdtvyscale}, + { XvGettable, 0, 0xffffffff, sisxvsdgetscreensize}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrir}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrig}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrib}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrir}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrig}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrib}, +#ifdef SIS_CP + SIS_CP_VIDEO_ATTRIBUTES +#endif +}; -static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +static XF86AttributeRec SISAttributes_315[NUM_ATTRIBUTES_315] = { - {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, - {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, - {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} + {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvcolorkey}, + {XvSettable | XvGettable, -128, 127, sisxvbrightness}, + {XvSettable | XvGettable, 0, 7, sisxvcontrast}, + {XvSettable | XvGettable, -7, 7, sisxvsaturation}, + {XvSettable | XvGettable, -8, 7, sisxvhue}, + {XvSettable | XvGettable, 0, 1, sisxvautopaintcolorkey}, + {XvSettable , 0, 0, sisxvsetdefaults}, + {XvSettable | XvGettable, -32, 32, sisxvtvxposition}, + {XvSettable | XvGettable, -32, 32, sisxvtvyposition}, + {XvSettable | XvGettable, 0, 1, sisxvdisablegfx}, + {XvSettable | XvGettable, 0, 1, sisxvdisablegfxlr}, + {XvSettable | XvGettable, 0, 1, sisxvdisablecolorkey}, + {XvSettable | XvGettable, 0, 1, sisxvusechromakey}, + {XvSettable | XvGettable, 0, 1, sisxvinsidechromakey}, +/* {XvSettable | XvGettable, 0, 1, sisxvyuvchromakey}, - NO, Chromakey format = Source format */ + {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvchromamin}, + {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvchromamax}, + { XvGettable, 0, 0xffffffff, sisxvqueryvbflags}, + { XvGettable, 0, 0xffffffff, sisxvsdgetdriverversion}, + { XvGettable, 0, 0xffffffff, sisxvsdgethardwareinfo}, + { XvGettable, 0, 0xffffffff, sisxvsdgetbusid}, + { XvGettable, 0, 0xffffffff, sisxvsdqueryvbflagsversion}, + { XvGettable, 0, 0xffffffff, sisxvsdgetsdflags}, + {XvSettable | XvGettable, 0, 0xffffffff, sisxvsdunlocksisdirect}, + {XvSettable , 0, 0xffffffff, sisxvsdsetvbflags}, + { XvGettable, 0, 0xffffffff, sisxvsdquerydetecteddevices}, + {XvSettable | XvGettable, 0, 1, sisxvsdcrt1status}, + {XvSettable , 0, 0xffffffff, sisxvsdcheckmodeindexforcrt2}, + { XvGettable, 0, 0xffffffff, sisxvsdresultcheckmodeindexforcrt2}, + {XvSettable | XvGettable, 0, 4, sisxvsdsisantiflicker}, + {XvSettable | XvGettable, 0, 15, sisxvsdsissaturation}, + {XvSettable | XvGettable, 0, 15, sisxvsdsisedgeenhance}, + {XvSettable | XvGettable, -128, 127, sisxvsdsiscolcalibf}, + {XvSettable | XvGettable, -120, 120, sisxvsdsiscolcalibc}, + {XvSettable | XvGettable, 0, 1, sisxvsdsiscfilter}, + {XvSettable | XvGettable, 0, 8, sisxvsdsisyfilter}, + {XvSettable | XvGettable, 0, 15, sisxvsdchcontrast}, + {XvSettable | XvGettable, 0, 15, sisxvsdchtextenhance}, + {XvSettable | XvGettable, 0, 15, sisxvsdchchromaflickerfilter}, + {XvSettable | XvGettable, 0, 15, sisxvsdchlumaflickerfilter}, + {XvSettable | XvGettable, 0, 1, sisxvsdchcvbscolor}, + {XvSettable | XvGettable, 0, 3, sisxvsdchoverscan}, + {XvSettable | XvGettable, 0, 3, sisxvsdenablegamma}, + {XvSettable | XvGettable, -16, 16, sisxvsdtvxscale}, + {XvSettable | XvGettable, -4, 3, sisxvsdtvyscale}, + { XvGettable, 0, 0xffffffff, sisxvsdgetscreensize}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrir}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrig}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrib}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrir}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrig}, + {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrib}, +#ifdef SIS_CP + SIS_CP_VIDEO_ATTRIBUTES +#endif + {XvSettable | XvGettable, 0, 1, sisxvswitchcrt}, }; -#define NUM_IMAGES 2 -#define PIXEL_FMT_YV12 0x32315659 -#define PIXEL_FMT_YUY2 0x32595559 - -static XF86ImageRec Images[NUM_IMAGES] = -{ - { - PIXEL_FMT_YUY2, - XvYUV, - LSBFirst, - {'Y','U','Y','2', - 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, - 16, - XvPacked, - 1, - 0, 0, 0, 0 , - 8, 8, 8, - 1, 2, 2, - 1, 1, 1, - {'Y','U','Y','V', - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - XvTopToBottom +#define NUM_IMAGES_300 6 +#define NUM_IMAGES_315 7 /* NV12 only - but does not work */ +#define NUM_IMAGES_330 9 /* NV12 and NV21 */ +#define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */ +#define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */ +#define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */ +#define PIXEL_FMT_I420 FOURCC_I420 /* 0x30323449 */ +#define PIXEL_FMT_RGB5 0x35315652 +#define PIXEL_FMT_RGB6 0x36315652 +#define PIXEL_FMT_YVYU 0x55595659 /* 315/330 only */ +#define PIXEL_FMT_NV12 0x3231564e /* 330 only */ +#define PIXEL_FMT_NV21 0x3132564e /* 330 only */ + +/* TODO: */ +#define PIXEL_FMT_RAW8 0x38574152 + +static XF86ImageRec SISImages[NUM_IMAGES_330] = +{ + XVIMAGE_YUY2, /* If order is changed, SISOffscreenImages must be adapted */ + XVIMAGE_YV12, + XVIMAGE_UYVY, + XVIMAGE_I420 + , + { /* RGB 555 */ + PIXEL_FMT_RGB5, + XvRGB, + LSBFirst, + {'R','V','1','5', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, +/* 15, 0x001F, 0x03E0, 0x7C00, - incorrect! */ + 15, 0x7C00, 0x03E0, 0x001F, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { /* RGB 565 */ + PIXEL_FMT_RGB6, + XvRGB, + LSBFirst, + {'R','V','1','6', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, +/* 16, 0x001F, 0x07E0, 0xF800, - incorrect! */ + 16, 0xF800, 0x07E0, 0x001F, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { /* YVYU */ + PIXEL_FMT_YVYU, \ + XvYUV, \ + LSBFirst, \ + {'Y','V','Y','U', + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, + 16, + XvPacked, + 1, + 0, 0, 0, 0, + 8, 8, 8, + 1, 2, 2, + 1, 1, 1, + {'Y','V','Y','U', + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { /* NV12 */ + PIXEL_FMT_NV12, + XvYUV, + LSBFirst, + {'N','V','1','2', + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, + 12, + XvPlanar, + 2, + 0, 0, 0, 0, + 8, 8, 8, + 1, 2, 2, + 1, 2, 2, + {'Y','U','V',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { /* NV21 */ + PIXEL_FMT_NV21, + XvYUV, + LSBFirst, + {'N','V','2','1', + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, + 12, + XvPlanar, + 2, + 0, 0, 0, 0, + 8, 8, 8, + 1, 2, 2, + 1, 2, 2, + {'Y','V','U',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom }, - { - PIXEL_FMT_YV12, - XvYUV, - LSBFirst, - {'Y','V','1','2', - 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, - 12, - XvPlanar, - 3, - 0, 0, 0, 0 , - 8, 8, 8, - 1, 2, 2, - 1, 2, 2, - {'Y','V','U', - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - XvTopToBottom - } }; typedef struct { - int pixelFormat; + int pixelFormat; + + CARD16 pitch; + CARD16 origPitch; + + CARD8 keyOP; + CARD16 HUSF; + CARD16 VUSF; + CARD8 IntBit; + CARD8 wHPre; + + CARD16 srcW; + CARD16 srcH; + + BoxRec dstBox; + + CARD32 PSY; + CARD32 PSV; + CARD32 PSU; + + CARD16 SCREENheight; + + CARD8 lineBufSize; + + DisplayModePtr currentmode; - CARD16 pitch; +#ifdef SISMERGED + CARD16 pitch2; + CARD16 HUSF2; + CARD16 VUSF2; + CARD8 IntBit2; + CARD8 wHPre2; - CARD8 keyOP; - CARD16 HUSF; - CARD16 VUSF; - CARD8 IntBit; - CARD8 wHPre; + CARD16 srcW2; + CARD16 srcH2; + BoxRec dstBox2; + CARD32 PSY2; + CARD32 PSV2; + CARD32 PSU2; + CARD16 SCREENheight2; + CARD8 lineBufSize2; - CARD16 srcW; - CARD16 srcH; + DisplayModePtr currentmode2; - BoxRec dstBox; + Bool DoFirst, DoSecond; +#endif - CARD32 PSY; - CARD32 PSV; - CARD32 PSU; - CARD8 bobEnable; + CARD8 bobEnable; - CARD8 contrastCtrl; - CARD8 contrastFactor; + CARD8 contrastCtrl; + CARD8 contrastFactor; - CARD8 lineBufSize; + CARD8 (*VBlankActiveFunc)(SISPtr); +#if 0 + CARD32 (*GetScanLineFunc)(SISPtr pSiS); +#endif - CARD8 (*VBlankActiveFunc)(SISPtr); - CARD32 (*GetScanLineFunc)(SISPtr pSIS); +#if 0 + /* TW: The following are not used yet */ + CARD16 SubPictHUSF; /* Subpicture scaling */ + CARD16 SubpictVUSF; + CARD8 SubpictIntBit; + CARD8 SubPictwHPre; + CARD16 SubPictsrcW; /* Subpicture source width */ + CARD16 SubPictsrcH; /* Subpicture source height */ + BoxRec SubPictdstBox; /* SubPicture destination box */ + CARD32 SubPictAddr; /* SubPicture address */ + CARD32 SubPictPitch; /* SubPicture pitch */ + CARD32 SubPictOrigPitch; /* SubPicture real pitch (needed for scaling twice) */ + CARD32 SubPictPreset; /* Subpicture Preset */ + + CARD32 MPEG_Y; /* MPEG Y Buffer Addr */ + CARD32 MPEG_UV; /* MPEG UV Buffer Addr */ +#endif + } SISOverlayRec, *SISOverlayPtr; typedef struct { - FBAreaPtr fbAreaPtr; - int fbSize; - CARD32 bufAddr[2]; + FBLinearPtr linear; + CARD32 bufAddr[2]; - unsigned char currentBuf; + unsigned char currentBuf; - short drw_x, drw_y, drw_w, drw_h; - short src_x, src_y, src_w, src_h; - int id; - short srcPitch, height; - - unsigned char brightness; - unsigned char contrast; + short drw_x, drw_y, drw_w, drw_h; + short src_x, src_y, src_w, src_h; + int id; + short srcPitch, height; + + char brightness; + unsigned char contrast; + char hue; + char saturation; + + RegionRec clip; + CARD32 colorKey; + Bool autopaintColorKey; - RegionRec clip; - CARD32 colorKey; + Bool disablegfx; + Bool disablegfxlr; - CARD32 videoStatus; - Time offTime; - Time freeTime; + Bool usechromakey; + Bool insidechromakey, yuvchromakey; + CARD32 chromamin, chromamax; - CARD32 displayMode; -} SISPortPrivRec, *SISPortPrivPtr; + CARD32 videoStatus; + BOOLEAN overlayStatus; + Time offTime; + Time freeTime; + + CARD32 displayMode; + Bool bridgeIsSlave; + + Bool hasTwoOverlays; /* Chipset has two overlays */ + Bool dualHeadMode; /* We're running in DHM */ + + Bool NoOverlay; + Bool PrevOverlay; + + Bool AllowSwitchCRT; + int crtnum; /* 0=CRT1, 1=CRT2 */ + + Bool needToScale; /* Need to scale video */ + + int shiftValue; /* 315/330 series need word addr/pitch, 300 series double word */ + + short linebufMergeLimit; + CARD8 linebufmask; + + short oldx1, oldx2, oldy1, oldy2; +#ifdef SISMERGED + short oldx1_2, oldx2_2, oldy1_2, oldy2_2; +#endif + int mustwait; + + Bool grabbedByV4L; /* V4L stuff */ + int pitch; + int offset; + + int modeflags; /* Flags field of current display mode */ + + int tvxpos, tvypos; + Bool updatetvxpos, updatetvypos; + +} SISPortPrivRec, *SISPortPrivPtr; #define GET_PORT_PRIVATE(pScrn) \ (SISPortPrivPtr)((SISPTR(pScrn))->adaptor->pPortPrivates[0].ptr) +static void +SISSetPortDefaults(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate;; +#endif + + pPriv->colorKey = pSiS->colorKey = 0x000101fe; + pPriv->videoStatus = 0; + pPriv->brightness = pSiS->XvDefBri; + pPriv->contrast = pSiS->XvDefCon; + pPriv->hue = pSiS->XvDefHue; + pPriv->saturation = pSiS->XvDefSat; + pPriv->autopaintColorKey = TRUE; + pPriv->disablegfx = pSiS->XvDefDisableGfx; + pPriv->disablegfxlr= pSiS->XvDefDisableGfxLR; + pSiS->disablecolorkeycurrent = pSiS->XvDisableColorKey; + pPriv->usechromakey = pSiS->XvUseChromaKey; + pPriv->insidechromakey = pSiS->XvInsideChromaKey; + pPriv->yuvchromakey = pSiS->XvYUVChromaKey; + pPriv->chromamin = pSiS->XvChromaMin; + pPriv->chromamax = pSiS->XvChromaMax; + if(pPriv->dualHeadMode) { +#ifdef SISDUALHEAD + if(!pSiS->SecondHead) { + pPriv->tvxpos = pSiS->tvxpos; + pPriv->tvypos = pSiS->tvypos; + pPriv->updatetvxpos = TRUE; + pPriv->updatetvypos = TRUE; + } +#endif + } else { + pPriv->tvxpos = pSiS->tvxpos; + pPriv->tvypos = pSiS->tvypos; + pPriv->updatetvxpos = TRUE; + pPriv->updatetvypos = TRUE; + } +#ifdef SIS_CP + SIS_CP_VIDEO_DEF +#endif + if(pPriv->dualHeadMode) + pPriv->crtnum = + pSiSEnt->curxvcrtnum = + pSiSEnt->XvOnCRT2 ? 1 : 0; + else + pPriv->crtnum = pSiS->XvOnCRT2 ? 1 : 0; +} -static void -SISResetVideo(ScrnInfoPtr pScrn) +static void +SISResetVideo(ScrnInfoPtr pScrn) { - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); - if (getsrreg (pSIS, 0x05) != 0xa1) - { - setsrreg (pSIS, 0x05, 0x86); - if (getsrreg (pSIS, 0x05) != 0xa1) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Standard password not initialize\n"); - } - if (getvideoreg (pSIS, Index_VI_Passwd) != 0xa1) - { - setvideoreg (pSIS, Index_VI_Passwd, 0x86); - if (getvideoreg (pSIS, Index_VI_Passwd) != 0xa1) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Video password not initialize\n"); + /* Unlock registers */ +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + if (getvideoreg (pSiS, Index_VI_Passwd) != 0xa1) { + setvideoreg (pSiS, Index_VI_Passwd, 0x86); + if (getvideoreg (pSiS, Index_VI_Passwd) != 0xa1) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Xv: Video password could not unlock registers\n"); + } + + /* Initialize first overlay (CRT1) ------------------------------- */ + + /* This bit has obviously a different meaning on 315 series (linebuffer-related) */ + if(pSiS->VGAEngine == SIS_300_VGA) { + /* Write-enable video registers */ + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x80, 0x81); + } else { + /* Select overlay 2, clear all linebuffer related bits */ + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0xb1); + } + + /* Disable overlay */ + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + + /* Disable bob de-interlacer and some strange bit */ + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x82); + + /* Select RGB chroma key format (300 series only) */ + if(pSiS->VGAEngine == SIS_300_VGA) { + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x40); + } + + /* Reset scale control and contrast */ + /* (Enable DDA (interpolation)) */ + setvideoregmask(pSiS, Index_VI_Scale_Control, 0x60, 0x60); + setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); + + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Low, 0x00); + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); + setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Low, 0x00); + setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Middle, 0x00); + setvideoreg(pSiS, Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); + setvideoreg(pSiS, Index_VI_Play_Threshold_Low, 0x00); + setvideoreg(pSiS, Index_VI_Play_Threshold_High, 0x00); + + if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { + /* What does this do? */ + setvideoregmask(pSiS, Index_VI_Key_Overlay_OP, 0x00, 0x10); + } + + if(pSiS->ChipFlags & SiSCF_Is65x) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x04); + } + + /* Initialize second overlay (CRT2) ---- only for 300, 630/730, 550, M650/651/652/653, 660 */ + if (pPriv->hasTwoOverlays) { + + if(pSiS->VGAEngine == SIS_300_VGA) { + /* Write-enable video registers */ + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x81, 0x81); + } else { + /* Select overlay 2, clear all linebuffer related bits */ + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0xb1); + } + + /* Disable overlay */ + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + + /* Disable bob de-interlacer and some strange bit */ + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x82); + + /* Select RGB chroma key format */ + if(pSiS->VGAEngine == SIS_300_VGA) { + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x40); + } else { + /* setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x01, 0x01); */ } - /* Initial first set */ - setvideoregmask (pSIS, Index_VI_Control_Misc2, 0x80, 0x81); - setvideoregmask(pSIS, Index_VI_Control_Misc0, 0x00, 0x02); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x02, 0x02); - setvideoregmask(pSIS, Index_VI_Scale_Control, 0x60, 0x60); - setvideoregmask(pSIS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); - - setvideoreg(pSIS, Index_VI_Disp_Y_Buf_Preset_Low, 0x00); - setvideoreg(pSIS, Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); - setvideoreg(pSIS, Index_VI_UV_Buf_Preset_Low, 0x00); - setvideoreg(pSIS, Index_VI_UV_Buf_Preset_Middle, 0x00); - setvideoreg(pSIS, Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); - setvideoreg(pSIS, Index_VI_Play_Threshold_Low, 0x00); - setvideoreg(pSIS, Index_VI_Play_Threshold_High, 0x00); - - /* Initial second set */ - setvideoregmask(pSIS, Index_VI_Control_Misc2, 0x81, 0x81); - setvideoregmask(pSIS, Index_VI_Control_Misc0, 0x00, 0x02); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x02, 0x02); - setvideoregmask(pSIS, Index_VI_Scale_Control, 0x60, 0x60); - setvideoregmask(pSIS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); - - setvideoreg(pSIS, Index_VI_Disp_Y_Buf_Preset_Low, 0x00); - setvideoreg(pSIS, Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); - setvideoreg(pSIS, Index_VI_UV_Buf_Preset_Low, 0x00); - setvideoreg(pSIS, Index_VI_UV_Buf_Preset_Middle, 0x00); - setvideoreg(pSIS, Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); - setvideoreg(pSIS, Index_VI_Play_Threshold_Low, 0x00); - setvideoreg(pSIS, Index_VI_Play_Threshold_High, 0x00); - - /* set default contrast */ - setvideoregmask (pSIS, Index_VI_Control_Misc2, 0x00, 0x01); - setvideoregmask (pSIS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); - setvideoreg (pSIS, Index_VI_Brightness, 0x20); + /* Reset scale control and contrast */ + /* (Enable DDA (interpolation)) */ + setvideoregmask(pSiS, Index_VI_Scale_Control, 0x60, 0x60); + setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); + + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Low, 0x00); + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); + setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Low, 0x00); + setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Middle, 0x00); + setvideoreg(pSiS, Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); + setvideoreg(pSiS, Index_VI_Play_Threshold_Low, 0x00); + setvideoreg(pSiS, Index_VI_Play_Threshold_High, 0x00); + + if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { + /* What does this do? */ + setvideoregmask(pSiS, Index_VI_Key_Overlay_OP, 0x00, 0x10); + } + } + + /* set default properties for overlay 1 (CRT1) -------------------------- */ + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x01); + setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); + setvideoreg(pSiS, Index_VI_Brightness, 0x20); + if(pSiS->VGAEngine == SIS_315_VGA) { + setvideoreg(pSiS, Index_VI_Hue, 0x00); + setvideoreg(pSiS, Index_VI_Saturation, 0x00); + } + + /* set default properties for overlay 2(CRT2) -------------------------- */ + if(pPriv->hasTwoOverlays) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x01); + setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); + setvideoreg(pSiS, Index_VI_Brightness, 0x20); + if(pSiS->VGAEngine == SIS_315_VGA) { + setvideoreg(pSiS, Index_VI_Hue, 0x00); + setvideoreg(pSiS, Index_VI_Saturation, 0x00); + } + } +} + +/* TW: Set display mode (single CRT1/CRT2, mirror). + * MIRROR mode is only available on chipsets with two overlays. + * On the other chipsets, if only CRT1 or only CRT2 are used, + * the correct display CRT is chosen automatically. If both + * CRT1 and CRT2 are connected, the user can choose between CRT1 and + * CRT2 by using the option XvOnCRT2. + */ +static void +set_dispmode(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) +{ + SISPtr pSiS = SISPTR(pScrn); + + pPriv->dualHeadMode = pPriv->bridgeIsSlave = FALSE; - setvideoregmask (pSIS, Index_VI_Control_Misc2, 0x01, 0x01); - setvideoregmask (pSIS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); - setvideoreg (pSIS, Index_VI_Brightness, 0x20); + if(SiSBridgeIsInSlaveMode(pScrn)) pPriv->bridgeIsSlave = TRUE; + if( (pSiS->VBFlags & VB_DISPMODE_MIRROR) || + ((pPriv->bridgeIsSlave) && (pSiS->VBFlags & DISPTYPE_DISP2)) ) { + if(pPriv->hasTwoOverlays) + pPriv->displayMode = DISPMODE_MIRROR; /* CRT1+CRT2 (2 overlays) */ + else if(pPriv->crtnum) + pPriv->displayMode = DISPMODE_SINGLE2; /* CRT2 only */ + else + pPriv->displayMode = DISPMODE_SINGLE1; /* CRT1 only */ + } else { +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pPriv->dualHeadMode = TRUE; + if(pSiS->SecondHead) + pPriv->displayMode = DISPMODE_SINGLE1; /* CRT1 only */ + else + pPriv->displayMode = DISPMODE_SINGLE2; /* CRT2 only */ + } else +#endif + if(pSiS->VBFlags & DISPTYPE_DISP1) { + pPriv->displayMode = DISPMODE_SINGLE1; /* CRT1 only */ + } else { + pPriv->displayMode = DISPMODE_SINGLE2; /* CRT2 only */ + } + } } +static void +set_disptype_regs(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + int crtnum = 0; + + if(pPriv->dualHeadMode) crtnum = pSiSEnt->curxvcrtnum; +#endif + + /* TW: + * SR06[7:6] + * Bit 7: Enable overlay 2 on CRT2 + * Bit 6: Enable overlay 1 on CRT2 + * SR32[7:6] + * Bit 7: DCLK/TCLK overlay 2 + * 0=DCLK (overlay on CRT1) + * 1=TCLK (overlay on CRT2) + * Bit 6: DCLK/TCLK overlay 1 + * 0=DCLK (overlay on CRT1) + * 1=TCLK (overlay on CRT2) + * + * On chipsets with two overlays, we can freely select and also + * have a mirror mode. However, we use overlay 1 for CRT1 and + * overlay 2 for CRT2. + * ATTENTION: CRT2 can only take up to 1 (one) overlay. Setting + * SR06/32 to 0xc0 DOES NOT WORK. THAT'S CONFIRMED. + * Therefore, we use overlay 1 on CRT2 if in SINGLE2 mode. + * + * For chipsets with only one overlay, user must choose whether + * to display the overlay on CRT1 or CRT2 by setting XvOnCRT2 + * to TRUE (CRT2) or FALSE (CRT1). The driver does this auto- + * matically if only CRT1 or only CRT2 is used. + */ +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif -static XF86VideoAdaptorPtr + switch (pPriv->displayMode) + { + case DISPMODE_SINGLE1: /* CRT1-only mode: */ + if(pPriv->hasTwoOverlays) { + if(pPriv->dualHeadMode) { + setsrregmask(pSiS, 0x06, 0x00, 0x40); /* overlay 1 -> CRT1 */ + setsrregmask(pSiS, 0x32, 0x00, 0x40); + } else { + setsrregmask(pSiS, 0x06, 0x00, 0xc0); /* both overlays -> CRT1 */ + setsrregmask(pSiS, 0x32, 0x00, 0xc0); + } + } else { +#ifdef SISDUALHEAD + if((!pPriv->dualHeadMode) || (crtnum == 0)) { +#endif + setsrregmask(pSiS, 0x06, 0x00, 0xc0); /* only overlay -> CRT1 */ + setsrregmask(pSiS, 0x32, 0x00, 0xc0); +#ifdef SISDUALHEAD + } +#endif + } + break; + + case DISPMODE_SINGLE2: /* CRT2-only mode: */ + if(pPriv->hasTwoOverlays) { + if(pPriv->dualHeadMode) { + setsrregmask(pSiS, 0x06, 0x80, 0x80); /* overlay 2 -> CRT2 */ + setsrregmask(pSiS, 0x32, 0x80, 0x80); + } else { + setsrregmask(pSiS, 0x06, 0x40, 0xc0); /* overlay 1 -> CRT2 */ + setsrregmask(pSiS, 0x32, 0xc0, 0xc0); /* (although both clocks for CRT2!) */ + } + } else { +#ifdef SISDUALHEAD + if((!pPriv->dualHeadMode) || (crtnum == 1)) { +#endif + setsrregmask(pSiS, 0x06, 0x40, 0xc0); /* only overlay -> CRT2 */ + setsrregmask(pSiS, 0x32, 0x40, 0xc0); +#ifdef SISDUALHEAD + } +#endif + } + break; + + case DISPMODE_MIRROR: /* CRT1+CRT2-mode: (only on chips with 2 overlays) */ + default: + setsrregmask(pSiS, 0x06, 0x80, 0xc0); /* overlay 1 -> CRT1, overlay 2 -> CRT2 */ + setsrregmask(pSiS, 0x32, 0x80, 0xc0); + break; + } +} + +static void +set_allowswitchcrt(SISPtr pSiS, SISPortPrivPtr pPriv) +{ + if(pSiS->hasTwoOverlays) { + pPriv->AllowSwitchCRT = FALSE; + } else { + pPriv->AllowSwitchCRT = TRUE; + if(pSiS->XvOnCRT2) { + if(!(pSiS->VBFlags & DISPTYPE_DISP1)) { + pPriv->AllowSwitchCRT = FALSE; + } + } else { + if(!(pSiS->VBFlags & DISPTYPE_DISP2)) { + pPriv->AllowSwitchCRT = FALSE; + } + } + } +} + +static void +set_maxencoding(SISPtr pSiS, SISPortPrivPtr pPriv) +{ + if(pSiS->VGAEngine == SIS_300_VGA) { + DummyEncoding.width = IMAGE_MAX_WIDTH_300; + DummyEncoding.height = IMAGE_MAX_HEIGHT_300; + } else { + DummyEncoding.width = IMAGE_MAX_WIDTH_315; + DummyEncoding.height = IMAGE_MAX_HEIGHT_315; + if(pPriv->hasTwoOverlays) { + /* Only half width available if both overlays + * are going to be used + */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + DummyEncoding.width >>= 1; + } else +#endif +#ifdef SISMERGED + if(pSiS->MergedFB) { + DummyEncoding.width >>= 1; + } else +#endif + if(pPriv->displayMode == DISPMODE_MIRROR) { + DummyEncoding.width >>= 1; + } + } + } +} + +static XF86VideoAdaptorPtr SISSetupImageVideo(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); XF86VideoAdaptorPtr adapt; SISPortPrivPtr pPriv; if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + - sizeof(SISPortPrivRec) + - sizeof(DevUnion)))) - return NULL; + sizeof(SISPortPrivRec) + + sizeof(DevUnion)))) + return NULL; adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - adapt->name = "SIS Video Overlay"; + adapt->name = "SIS 300/315/330 series Video Overlay"; adapt->nEncodings = 1; - adapt->pEncodings = DummyEncoding; + adapt->pEncodings = &DummyEncoding; + adapt->nFormats = NUM_FORMATS; - adapt->pFormats = Formats; + adapt->pFormats = SISFormats; adapt->nPorts = 1; adapt->pPortPrivates = (DevUnion*)(&adapt[1]); pPriv = (SISPortPrivPtr)(&adapt->pPortPrivates[1]); + + /* Setup chipset type helpers */ + if(pSiS->hasTwoOverlays) { + pPriv->hasTwoOverlays = TRUE; + pPriv->AllowSwitchCRT = FALSE; + } else { + pPriv->hasTwoOverlays = FALSE; + pPriv->AllowSwitchCRT = TRUE; + if(pSiS->XvOnCRT2) { + if(!(pSiS->VBFlags & DISPTYPE_DISP1)) { + pPriv->AllowSwitchCRT = FALSE; + } + } else { + if(!(pSiS->VBFlags & DISPTYPE_DISP2)) { + pPriv->AllowSwitchCRT = FALSE; + } + } + } + + set_allowswitchcrt(pSiS, pPriv); adapt->pPortPrivates[0].ptr = (pointer)(pPriv); - adapt->pAttributes = Attributes; - adapt->nImages = 2; - adapt->nAttributes = 3; - adapt->pImages = Images; + if(pSiS->VGAEngine == SIS_300_VGA) { + adapt->nImages = NUM_IMAGES_300; + adapt->pAttributes = SISAttributes_300; + adapt->nAttributes = NUM_ATTRIBUTES_300; + } else { + if(pSiS->sishw_ext.jChipType >= SIS_330) { + adapt->nImages = NUM_IMAGES_330; + } else { + adapt->nImages = NUM_IMAGES_315; + } + adapt->pAttributes = SISAttributes_315; + adapt->nAttributes = NUM_ATTRIBUTES_315; + if(pPriv->hasTwoOverlays) adapt->nAttributes--; + } + + adapt->pImages = SISImages; adapt->PutVideo = NULL; adapt->PutStill = NULL; adapt->GetVideo = NULL; @@ -476,47 +1176,145 @@ SISSetupImageVideo(ScreenPtr pScreen) adapt->PutImage = SISPutImage; adapt->QueryImageAttributes = SISQueryImageAttributes; - pPriv->colorKey = 0x000101fe; pPriv->videoStatus = 0; - pPriv->brightness = 0; - pPriv->contrast = 128; - - pPriv->currentBuf = 0; - - pPriv->fbAreaPtr = NULL; - pPriv->fbSize = 0; + pPriv->currentBuf = 0; + pPriv->linear = NULL; + pPriv->grabbedByV4L= FALSE; + pPriv->NoOverlay = FALSE; + pPriv->PrevOverlay = FALSE; /* gotta uninit this someplace */ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); - pSIS->adaptor = adapt; - - pSIS->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = SISBlockHandler; + pSiS->adaptor = adapt; + + pSiS->xvBrightness = MAKE_ATOM(sisxvbrightness); + pSiS->xvContrast = MAKE_ATOM(sisxvcontrast); + pSiS->xvColorKey = MAKE_ATOM(sisxvcolorkey); + pSiS->xvSaturation = MAKE_ATOM(sisxvsaturation); + pSiS->xvHue = MAKE_ATOM(sisxvhue); + pSiS->xvSwitchCRT = MAKE_ATOM(sisxvswitchcrt); + pSiS->xvAutopaintColorKey = MAKE_ATOM(sisxvautopaintcolorkey); + pSiS->xvSetDefaults = MAKE_ATOM(sisxvsetdefaults); + pSiS->xvDisableGfx = MAKE_ATOM(sisxvdisablegfx); + pSiS->xvDisableGfxLR = MAKE_ATOM(sisxvdisablegfxlr); + pSiS->xvTVXPosition = MAKE_ATOM(sisxvtvxposition); + pSiS->xvTVYPosition = MAKE_ATOM(sisxvtvyposition); + pSiS->xvDisableColorkey = MAKE_ATOM(sisxvdisablecolorkey); + pSiS->xvUseChromakey = MAKE_ATOM(sisxvusechromakey); + pSiS->xvInsideChromakey = MAKE_ATOM(sisxvinsidechromakey); + pSiS->xvYUVChromakey = MAKE_ATOM(sisxvyuvchromakey); + pSiS->xvChromaMin = MAKE_ATOM(sisxvchromamin); + pSiS->xvChromaMax = MAKE_ATOM(sisxvchromamax); + pSiS->xv_QVF = MAKE_ATOM(sisxvqueryvbflags); + pSiS->xv_GDV = MAKE_ATOM(sisxvsdgetdriverversion); + pSiS->xv_GHI = MAKE_ATOM(sisxvsdgethardwareinfo); + pSiS->xv_GBI = MAKE_ATOM(sisxvsdgetbusid); + pSiS->xv_QVV = MAKE_ATOM(sisxvsdqueryvbflagsversion); + pSiS->xv_GSF = MAKE_ATOM(sisxvsdgetsdflags); + pSiS->xv_USD = MAKE_ATOM(sisxvsdunlocksisdirect); + pSiS->xv_SVF = MAKE_ATOM(sisxvsdsetvbflags); + pSiS->xv_QDD = MAKE_ATOM(sisxvsdquerydetecteddevices); + pSiS->xv_CT1 = MAKE_ATOM(sisxvsdcrt1status); + pSiS->xv_CMD = MAKE_ATOM(sisxvsdcheckmodeindexforcrt2); + pSiS->xv_CMDR = MAKE_ATOM(sisxvsdresultcheckmodeindexforcrt2); + pSiS->xv_TAF = MAKE_ATOM(sisxvsdsisantiflicker); + pSiS->xv_TSA = MAKE_ATOM(sisxvsdsissaturation); + pSiS->xv_TEE = MAKE_ATOM(sisxvsdsisedgeenhance); + pSiS->xv_COC = MAKE_ATOM(sisxvsdsiscolcalibc); + pSiS->xv_COF = MAKE_ATOM(sisxvsdsiscolcalibf); + pSiS->xv_CFI = MAKE_ATOM(sisxvsdsiscfilter); + pSiS->xv_YFI = MAKE_ATOM(sisxvsdsisyfilter); + pSiS->xv_TCO = MAKE_ATOM(sisxvsdchcontrast); + pSiS->xv_TTE = MAKE_ATOM(sisxvsdchtextenhance); + pSiS->xv_TCF = MAKE_ATOM(sisxvsdchchromaflickerfilter); + pSiS->xv_TLF = MAKE_ATOM(sisxvsdchlumaflickerfilter); + pSiS->xv_TCC = MAKE_ATOM(sisxvsdchcvbscolor); + pSiS->xv_OVR = MAKE_ATOM(sisxvsdchoverscan); + pSiS->xv_SGA = MAKE_ATOM(sisxvsdenablegamma); + pSiS->xv_TXS = MAKE_ATOM(sisxvsdtvxscale); + pSiS->xv_TYS = MAKE_ATOM(sisxvsdtvyscale); + pSiS->xv_GSS = MAKE_ATOM(sisxvsdgetscreensize); + pSiS->xv_BRR = MAKE_ATOM(sisxvsdstorebrir); + pSiS->xv_BRG = MAKE_ATOM(sisxvsdstorebrig); + pSiS->xv_BRB = MAKE_ATOM(sisxvsdstorebrib); + pSiS->xv_PBR = MAKE_ATOM(sisxvsdstorepbrir); + pSiS->xv_PBG = MAKE_ATOM(sisxvsdstorepbrig); + pSiS->xv_PBB = MAKE_ATOM(sisxvsdstorepbrib); +#ifdef SIS_CP + SIS_CP_VIDEO_ATOMS +#endif - xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); - xvContrast = MAKE_ATOM("XV_CONTRAST"); - xvColorKey = MAKE_ATOM("XV_COLORKEY"); + pSiS->xv_sisdirectunlocked = FALSE; + pSiS->xv_sd_result = 0; - /* set display mode */ - /* TODO: support CRT2-only mode */ - if(pSIS->VBFlags) { - pPriv->displayMode = DISPMODE_MIRROR; - setsrregmask (pSIS, 0x06, 0x80, 0xc0); - setsrregmask (pSIS, 0x32, 0x80, 0xc0); + /* 300 series require double words for addresses and pitches, + * 315 series require word. + */ + switch (pSiS->VGAEngine) { + case SIS_315_VGA: + pPriv->shiftValue = 1; + break; + case SIS_300_VGA: + default: + pPriv->shiftValue = 2; + break; } - else { - pPriv->displayMode = DISPMODE_SINGLE1; - setsrregmask (pSIS, 0x06, 0x00, 0xc0); - setsrregmask (pSIS, 0x32, 0x00, 0xc0); + + /* Set displayMode according to VBFlags */ + set_dispmode(pScrn, pPriv); + + /* Now for the linebuffer stuff. + * All chipsets have a certain number of linebuffers, each of a certain + * size. The number of buffers is per overlay. + * Chip number size max video size + * 300 2 ? ? + * 630/730 2 ? ? + * 315 2 960? 1920x1080 + * 650/740 2 960 ("120x128") 1920x1080 + * M650/651.. 4 480 1920x1080 + * 330 2 960? 1920x1080? + * 660 ? ? ? + * The unit of size is unknown; I just know that a size of 480 limits + * the video source width to 384. Beyond that, line buffers must be + * merged (otherwise the video output is garbled). + * To use the maximum width (eg 1920x1080 on the 315 series, including + * the M650, 651 and later), *all* line buffers must be merged. Hence, + * we can only use one overlay. This should be set up for modes where + * either only CRT1 or only CRT2 is used. + * If both overlays are going to be used (such as in modes were both + * CRT1 and CRT2 are active), we are limited to the half of the + * maximum width. + */ + + pPriv->linebufMergeLimit = LINEBUFLIMIT1; + + set_maxencoding(pSiS, pPriv); + + if(pSiS->VGAEngine == SIS_300_VGA) { + pPriv->linebufmask = 0x11; + } else { + pPriv->linebufmask = 0xb1; + if(!(pPriv->hasTwoOverlays)) { + /* On machines with only one overlay, the linebuffers are + * generally larger, so our merging-limit is higher, too. + */ + pPriv->linebufMergeLimit = LINEBUFLIMIT2; + } } + + /* Reset the properties to their defaults */ + SISSetPortDefaults(pScrn, pPriv); + + /* Set SR(06, 32) registers according to DISPMODE */ + set_disptype_regs(pScrn, pPriv); SISResetVideo(pScrn); return adapt; } - +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) static Bool RegionsEqual(RegionPtr A, RegionPtr B) { @@ -525,53 +1323,287 @@ RegionsEqual(RegionPtr A, RegionPtr B) num = REGION_NUM_RECTS(A); if(num != REGION_NUM_RECTS(B)) - return FALSE; + return FALSE; if((A->extents.x1 != B->extents.x1) || (A->extents.x2 != B->extents.x2) || (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) - return FALSE; + return FALSE; dataA = (int*)REGION_RECTS(A); dataB = (int*)REGION_RECTS(B); while(num--) { - if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) - return FALSE; - dataA += 2; - dataB += 2; + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; } return TRUE; } +#endif - - -static int -SISSetPortAttribute( - ScrnInfoPtr pScrn, - Atom attribute, - INT32 value, - pointer data -){ +static int +SISSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 value, pointer data) +{ SISPortPrivPtr pPriv = (SISPortPrivPtr)data; - - if(attribute == xvBrightness) { - if((value < -128) || (value > 127)) - return BadValue; - pPriv->brightness = value; - } else - if(attribute == xvContrast) { - if((value < 0) || (value > 255)) - return BadValue; - pPriv->contrast = value; - } else - if(attribute == xvColorKey) { - pPriv->colorKey = value; - REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate;; +#endif + + if(attribute == pSiS->xvBrightness) { + if((value < -128) || (value > 127)) + return BadValue; + pPriv->brightness = value; + } else if(attribute == pSiS->xvContrast) { + if((value < 0) || (value > 7)) + return BadValue; + pPriv->contrast = value; + } else if(attribute == pSiS->xvColorKey) { + pPriv->colorKey = pSiS->colorKey = value; + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + } else if(attribute == pSiS->xvAutopaintColorKey) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->autopaintColorKey = value; + } else if(attribute == pSiS->xvSetDefaults) { + SISSetPortDefaults(pScrn, pPriv); + } else if(attribute == pSiS->xvDisableGfx) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->disablegfx = value; + } else if(attribute == pSiS->xvDisableGfxLR) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->disablegfxlr = value; + } else if(attribute == pSiS->xvTVXPosition) { + if((value < -32) || (value > 32)) + return BadValue; + pPriv->tvxpos = value; + if(pSiS->xv_sisdirectunlocked) { + SiS_SetTVxposoffset(pScrn, pPriv->tvxpos); + pPriv->updatetvxpos = FALSE; + } else { + pSiS->tvxpos = pPriv->tvxpos; +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) pSiSEnt->tvxpos = pPriv->tvxpos; +#endif + pPriv->updatetvxpos = TRUE; + } + } else if(attribute == pSiS->xvTVYPosition) { + if((value < -32) || (value > 32)) + return BadValue; + pPriv->tvypos = value; + if(pSiS->xv_sisdirectunlocked) { + SiS_SetTVyposoffset(pScrn, pPriv->tvypos); + pPriv->updatetvypos = FALSE; + } else { + pSiS->tvypos = pPriv->tvypos; +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) pSiSEnt->tvypos = pPriv->tvypos; +#endif + pPriv->updatetvypos = TRUE; + } + } else if(attribute == pSiS->xvDisableColorkey) { + if((value < 0) || (value > 1)) + return BadValue; + pSiS->disablecolorkeycurrent = value; + } else if(attribute == pSiS->xvUseChromakey) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->usechromakey = value; + } else if(attribute == pSiS->xvInsideChromakey) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->insidechromakey = value; + } else if(attribute == pSiS->xvYUVChromakey) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->yuvchromakey = value; + } else if(attribute == pSiS->xvChromaMin) { + pPriv->chromamin = value; + } else if(attribute == pSiS->xvChromaMax) { + pPriv->chromamax = value; + } else if(attribute == pSiS->xv_USD) { + if((pSiS->enablesisctrl) && (value == SIS_DIRECTKEY)) + pSiS->xv_sisdirectunlocked = TRUE; + else + pSiS->xv_sisdirectunlocked = FALSE; + } else if(attribute == pSiS->xv_SVF) { +#ifdef SISDUALHEAD + if(!pPriv->dualHeadMode) +#endif + if(pSiS->xv_sisdirectunlocked) { + SISSwitchCRT2Type(pScrn, (unsigned long)value); + set_allowswitchcrt(pSiS, pPriv); + set_maxencoding(pSiS, pPriv); + } + } else if(attribute == pSiS->xv_CT1) { +#ifdef SISDUALHEAD + if(!pPriv->dualHeadMode) +#endif + if(pSiS->xv_sisdirectunlocked) { + SISSwitchCRT1Status(pScrn, (unsigned long)value); + set_allowswitchcrt(pSiS, pPriv); + set_maxencoding(pSiS, pPriv); + } + } else if(attribute == pSiS->xv_TAF) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetSISTVantiflicker(pScrn, (int)value); + } + } else if(attribute == pSiS->xv_TSA) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetSISTVsaturation(pScrn, (int)value); + } + } else if(attribute == pSiS->xv_TEE) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetSISTVedgeenhance(pScrn, (int)value); + } + } else if(attribute == pSiS->xv_CFI) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetSISTVcfilter(pScrn, value ? 1 : 0); + } + } else if(attribute == pSiS->xv_YFI) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetSISTVyfilter(pScrn, value); + } + } else if(attribute == pSiS->xv_COC) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetSISTVcolcalib(pScrn, (int)value, TRUE); + } + } else if(attribute == pSiS->xv_COF) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetSISTVcolcalib(pScrn, (int)value, FALSE); + } + } else if(attribute == pSiS->xv_TCO) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetCHTVcontrast(pScrn, (int)value); + } + } else if(attribute == pSiS->xv_TTE) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetCHTVtextenhance(pScrn, (int)value); + } + } else if(attribute == pSiS->xv_TCF) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetCHTVchromaflickerfilter(pScrn, (int)value); + } + } else if(attribute == pSiS->xv_TLF) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetCHTVlumaflickerfilter(pScrn, (int)value); + } + } else if(attribute == pSiS->xv_TCC) { + if(pSiS->xv_sisdirectunlocked) { + SiS_SetCHTVcvbscolor(pScrn, value ? 1 : 0); + } + } else if(attribute == pSiS->xv_OVR) { + if(pSiS->xv_sisdirectunlocked) { + pSiS->UseCHOverScan = -1; + pSiS->OptTVSOver = FALSE; + if(value == 3) { + if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSOVER) { + pSiS->OptTVSOver = TRUE; + } + pSiS->UseCHOverScan = 1; + } else if(value == 2) pSiS->UseCHOverScan = 1; + else if(value == 1) pSiS->UseCHOverScan = 0; + } + } else if(attribute == pSiS->xv_CMD) { + if(pSiS->xv_sisdirectunlocked) { + pSiS->xv_sd_result = (value & 0xffffff00); + if(SISCheckModeIndexForCRT2Type(pScrn, (unsigned short)(value & 0xff), + (unsigned short)((value >> 8) & 0xff))) { + pSiS->xv_sd_result |= 0x01; + } + } + } else if(attribute == pSiS->xv_SGA) { + if(pSiS->xv_sisdirectunlocked) { +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) { + pSiSEnt->CRT1gamma = (value & 0x01) ? TRUE : FALSE; + pSiSEnt->CRT2gamma = (value & 0x02) ? TRUE : FALSE; + } else { +#endif + pSiS->CRT1gamma = (value & 0x01) ? TRUE : FALSE; + pSiS->CRT2gamma = (value & 0x02) ? TRUE : FALSE; +#ifdef SISDUALHEAD + } +#endif + } + } else if(attribute == pSiS->xv_TXS) { + if((value < -16) || (value > 16)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + SiS_SetTVxscale(pScrn, value); + } + } else if(attribute == pSiS->xv_TYS) { + if((value < -4) || (value > 3)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + SiS_SetTVyscale(pScrn, value); + } + } else if(attribute == pSiS->xv_BRR) { + if((value < 100) || (value > 10000)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + pSiS->GammaBriR = value; + } + } else if(attribute == pSiS->xv_BRG) { + if((value < 100) || (value > 10000)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + pSiS->GammaBriG = value; + } + } else if(attribute == pSiS->xv_BRB) { + if((value < 100) || (value > 10000)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + pSiS->GammaBriB = value; + } + } else if(attribute == pSiS->xv_PBR) { + if((value < 100) || (value > 10000)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + pSiS->GammaPBriR = value; + } + } else if(attribute == pSiS->xv_PBG) { + if((value < 100) || (value > 10000)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + pSiS->GammaPBriG = value; + } + } else if(attribute == pSiS->xv_PBB) { + if((value < 100) || (value > 10000)) + return BadValue; + if(pSiS->xv_sisdirectunlocked) { + pSiS->GammaPBriB = value; + } +#ifdef SIS_CP + SIS_CP_VIDEO_SETATTRIBUTE +#endif + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if(attribute == pSiS->xvSwitchCRT) { + if(pPriv->AllowSwitchCRT) { + if((value < 0) || (value > 1)) + return BadValue; + pPriv->crtnum = value; +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) pSiSEnt->curxvcrtnum = value; +#endif + } + } else if(attribute == pSiS->xvHue) { + if((value < -8) || (value > 7)) + return BadValue; + pPriv->hue = value; + } else if(attribute == pSiS->xvSaturation) { + if((value < -7) || (value > 7)) + return BadValue; + pPriv->saturation = value; + } else return BadMatch; } else return BadMatch; - return Success; } @@ -583,523 +1615,1743 @@ SISGetPortAttribute( pointer data ){ SISPortPrivPtr pPriv = (SISPortPrivPtr)data; - - if(attribute == xvBrightness) { - *value = pPriv->brightness; - } else - if(attribute == xvContrast) { - *value = pPriv->contrast; - } else - if(attribute == xvColorKey) { - *value = pPriv->colorKey; + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate;; +#endif + + if(attribute == pSiS->xvBrightness) { + *value = pPriv->brightness; + } else if(attribute == pSiS->xvContrast) { + *value = pPriv->contrast; + } else if(attribute == pSiS->xvColorKey) { + *value = pPriv->colorKey; + } else if(attribute == pSiS->xvAutopaintColorKey) { + *value = (pPriv->autopaintColorKey) ? 1 : 0; + } else if(attribute == pSiS->xvDisableGfx) { + *value = (pPriv->disablegfx) ? 1 : 0; + } else if(attribute == pSiS->xvDisableGfxLR) { + *value = (pPriv->disablegfxlr) ? 1 : 0; + } else if(attribute == pSiS->xvTVXPosition) { + *value = SiS_GetTVxposoffset(pScrn); /* pPriv->tvxpos; */ + } else if(attribute == pSiS->xvTVYPosition) { + *value = SiS_GetTVyposoffset(pScrn); /* pPriv->tvypos; */ + } else if(attribute == pSiS->xvDisableColorkey) { + *value = (pSiS->disablecolorkeycurrent) ? 1 : 0; + } else if(attribute == pSiS->xvUseChromakey) { + *value = (pPriv->usechromakey) ? 1 : 0; + } else if(attribute == pSiS->xvInsideChromakey) { + *value = (pPriv->insidechromakey) ? 1 : 0; + } else if(attribute == pSiS->xvYUVChromakey) { + *value = (pPriv->yuvchromakey) ? 1 : 0; + } else if(attribute == pSiS->xvChromaMin) { + *value = pPriv->chromamin; + } else if(attribute == pSiS->xvChromaMax) { + *value = pPriv->chromamax; + } else if(attribute == pSiS->xv_QVF) { + *value = pSiS->VBFlags; + } else if(attribute == pSiS->xv_GDV) { + *value = SISDRIVERIVERSION; + } else if(attribute == pSiS->xv_GHI) { + *value = (pSiS->ChipFlags & 0xffff) | (pSiS->sishw_ext.jChipType << 16) | (pSiS->ChipRev << 24); + } else if(attribute == pSiS->xv_GBI) { + *value = (pSiS->PciInfo->bus << 16) | (pSiS->PciInfo->device << 8) | pSiS->PciInfo->func; + } else if(attribute == pSiS->xv_QVV) { + *value = SIS_VBFlagsVersion; + } else if(attribute == pSiS->xv_QDD) { + *value = pSiS->detectedCRT2Devices; + } else if(attribute == pSiS->xv_CT1) { + *value = pSiS->CRT1isoff ? 0 : 1; + } else if(attribute == pSiS->xv_GSF) { + *value = pSiS->SiS_SD_Flags; + } else if(attribute == pSiS->xv_USD) { + *value = pSiS->xv_sisdirectunlocked ? 1 : 0; + } else if(attribute == pSiS->xv_TAF) { + *value = SiS_GetSISTVantiflicker(pScrn); + } else if(attribute == pSiS->xv_TSA) { + *value = SiS_GetSISTVsaturation(pScrn); + } else if(attribute == pSiS->xv_TEE) { + *value = SiS_GetSISTVedgeenhance(pScrn); + } else if(attribute == pSiS->xv_CFI) { + *value = SiS_GetSISTVcfilter(pScrn); + } else if(attribute == pSiS->xv_YFI) { + *value = SiS_GetSISTVyfilter(pScrn); + } else if(attribute == pSiS->xv_COC) { + *value = SiS_GetSISTVcolcalib(pScrn, TRUE); + } else if(attribute == pSiS->xv_COF) { + *value = SiS_GetSISTVcolcalib(pScrn, FALSE); + } else if(attribute == pSiS->xv_TCO) { + *value = SiS_GetCHTVcontrast(pScrn); + } else if(attribute == pSiS->xv_TTE) { + *value = SiS_GetCHTVtextenhance(pScrn); + } else if(attribute == pSiS->xv_TCF) { + *value = SiS_GetCHTVchromaflickerfilter(pScrn); + } else if(attribute == pSiS->xv_TLF) { + *value = SiS_GetCHTVlumaflickerfilter(pScrn); + } else if(attribute == pSiS->xv_TCC) { + *value = SiS_GetCHTVcvbscolor(pScrn); + } else if(attribute == pSiS->xv_CMDR) { + *value = pSiS->xv_sd_result; + } else if(attribute == pSiS->xv_OVR) { + *value = 0; + if(pSiS->OptTVSOver == 1) *value = 3; + else if(pSiS->UseCHOverScan == 1) *value = 2; + else if(pSiS->UseCHOverScan == 0) *value = 1; + } else if(attribute == pSiS->xv_SGA) { + *value = 0; +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) { + if(pSiSEnt->CRT1gamma) *value |= 0x01; + if(pSiSEnt->CRT2gamma) *value |= 0x02; + } else { +#endif + if(pSiS->CRT1gamma) *value |= 0x01; + if(pSiS->CRT2gamma) *value |= 0x02; +#ifdef SISDUALHEAD + } +#endif + } else if(attribute == pSiS->xv_TXS) { + *value = SiS_GetTVxscale(pScrn); + } else if(attribute == pSiS->xv_TYS) { + *value = SiS_GetTVyscale(pScrn); + } else if(attribute == pSiS->xv_GSS) { + *value = (pScrn->virtualX << 16) | pScrn->virtualY; + } else if(attribute == pSiS->xv_BRR) { + *value = pSiS->GammaBriR; + } else if(attribute == pSiS->xv_BRG) { + *value = pSiS->GammaBriG; + } else if(attribute == pSiS->xv_BRB) { + *value = pSiS->GammaBriB; + } else if(attribute == pSiS->xv_PBR) { + *value = pSiS->GammaPBriR; + } else if(attribute == pSiS->xv_PBG) { + *value = pSiS->GammaPBriG; + } else if(attribute == pSiS->xv_PBB) { + *value = pSiS->GammaPBriB; +#ifdef SIS_CP + SIS_CP_VIDEO_GETATTRIBUTE +#endif + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if(attribute == pSiS->xvSwitchCRT) { +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) + *value = pSiSEnt->curxvcrtnum; + else +#endif + *value = pPriv->crtnum; + } else if(attribute == pSiS->xvHue) { + *value = pPriv->hue; + } else if(attribute == pSiS->xvSaturation) { + *value = pPriv->saturation; + } else return BadMatch; } else return BadMatch; - return Success; } -static void +static void SISQueryBestSize( - ScrnInfoPtr pScrn, + ScrnInfoPtr pScrn, Bool motion, - short vid_w, short vid_h, - short drw_w, short drw_h, + short vid_w, short vid_h, + short drw_w, short drw_h, unsigned int *p_w, unsigned int *p_h, pointer data ){ *p_w = drw_w; *p_h = drw_h; - - /* TODO: report the HW limitation */ } - static void -set_scale_factor(SISOverlayPtr pOverlay) +calc_scale_factor(SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, + SISPortPrivPtr pPriv, int index, int iscrt2) { - CARD32 I=0; - + SISPtr pSiS = SISPTR(pScrn); + CARD32 I=0,mult=0; + int flag=0; + int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1; - int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1; + int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1; int srcW = pOverlay->srcW; int srcH = pOverlay->srcH; - - int srcPitch = pOverlay->pitch; - - if (dstW == srcW) { - pOverlay->HUSF = 0x00; - pOverlay->IntBit = 0x05; + CARD16 LCDheight = pSiS->LCDheight; + int srcPitch = pOverlay->origPitch; + int origdstH = dstH; + int modeflags = pOverlay->currentmode->Flags; + + /* TW: Stretch image due to panel link scaling */ + if(pSiS->VBFlags & CRT2_LCD) { + if(pPriv->bridgeIsSlave) { + if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) { + if(pSiS->MiscFlags & MISC_PANELLINKSCALER) { + dstH = (dstH * LCDheight) / pOverlay->SCREENheight; + } } - else if (dstW > srcW) { - dstW += 2; - pOverlay->HUSF = (srcW << 16) / dstW; - pOverlay->IntBit = 0x04; - } - else { - int tmpW = dstW; - - I = 0x00; - pOverlay->IntBit = 0x01; - while (srcW >= tmpW) - { - tmpW <<= 1; - I++; + } else if(iscrt2) { + if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) { + if(pSiS->MiscFlags & MISC_PANELLINKSCALER) { + dstH = (dstH * LCDheight) / pOverlay->SCREENheight; + if (pPriv->displayMode == DISPMODE_MIRROR) flag = 1; + } + } + } + } + + /* TW: For double scan modes, we need to double the height + * On 315 and 550 (?), we need to double the width as well. + * Interlace mode vice versa. + */ + if(modeflags & V_DBLSCAN) { + dstH = origdstH << 1; + flag = 0; + if((pSiS->sishw_ext.jChipType >= SIS_315H) && + (pSiS->sishw_ext.jChipType <= SIS_550)) { + dstW <<= 1; } - pOverlay->wHPre = (CARD8)(I - 1); - dstW <<= (I - 1); - if ((srcW % dstW)) - pOverlay->HUSF = ((srcW - dstW) << 16) / dstW; - else - pOverlay->HUSF = 0x00; + } + if(modeflags & V_INTERLACE) { + dstH = origdstH >> 1; + flag = 0; + } + +#if 0 + /* TEST @@@ */ + if(pOverlay->bobEnable & 0x08) dstH <<= 1; +#endif + + if(dstW < OVERLAY_MIN_WIDTH) dstW = OVERLAY_MIN_WIDTH; + if (dstW == srcW) { + pOverlay->HUSF = 0x00; + pOverlay->IntBit = 0x05; + pOverlay->wHPre = 0; + } else if (dstW > srcW) { + dstW += 2; + pOverlay->HUSF = (srcW << 16) / dstW; + pOverlay->IntBit = 0x04; + pOverlay->wHPre = 0; + } else { + int tmpW = dstW; + + /* TW: It seems, the hardware can't scale below factor .125 (=1/8) if the + pitch isn't a multiple of 256. + TODO: Test this on the 315 series! + */ + if((srcPitch % 256) || (srcPitch < 256)) { + if(((dstW * 1000) / srcW) < 125) dstW = tmpW = ((srcW * 125) / 1000) + 1; } - if (dstH == srcH) { - pOverlay->VUSF = 0x00; - pOverlay->IntBit |= 0x0A; + I = 0; + pOverlay->IntBit = 0x01; + while (srcW >= tmpW) { + tmpW <<= 1; + I++; + } + pOverlay->wHPre = (CARD8)(I - 1); + dstW <<= (I - 1); + if ((srcW % dstW)) + pOverlay->HUSF = ((srcW - dstW) << 16) / dstW; + else + pOverlay->HUSF = 0x00; + } + + if(dstH < OVERLAY_MIN_HEIGHT) dstH = OVERLAY_MIN_HEIGHT; + if (dstH == srcH) { + pOverlay->VUSF = 0x00; + pOverlay->IntBit |= 0x0A; + } else if (dstH > srcH) { + dstH += 0x02; + pOverlay->VUSF = (srcH << 16) / dstH; + pOverlay->IntBit |= 0x08; + } else { + CARD32 realI; + + I = realI = srcH / dstH; + pOverlay->IntBit |= 0x02; + + if (I < 2) { + pOverlay->VUSF = ((srcH - dstH) << 16) / dstH; + /* TW: Needed for LCD-scaling modes */ + if((flag) && (mult = (srcH / origdstH)) >= 2) + pOverlay->pitch /= mult; + } else { +#if 0 + if (((pOverlay->bobEnable & 0x08) == 0x00) && + (((srcPitch * I)>>2) > 0xFFF)){ + pOverlay->bobEnable |= 0x08; + srcPitch >>= 1; + } +#endif + if (((srcPitch * I)>>2) > 0xFFF) { + I = (0xFFF*2/srcPitch); + pOverlay->VUSF = 0xFFFF; + } else { + dstH = I * dstH; + if (srcH % dstH) + pOverlay->VUSF = ((srcH - dstH) << 16) / dstH; + else + pOverlay->VUSF = 0x00; + } + /* set video frame buffer offset */ + pOverlay->pitch = (CARD16)(srcPitch*I); + } + } +} + +#ifdef SISMERGED +static void +calc_scale_factor_2(SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, + SISPortPrivPtr pPriv, int index, int iscrt2) +{ + SISPtr pSiS = SISPTR(pScrn); + CARD32 I=0,mult=0; + int flag=0; + + int dstW = pOverlay->dstBox2.x2 - pOverlay->dstBox2.x1; + int dstH = pOverlay->dstBox2.y2 - pOverlay->dstBox2.y1; + int srcW = pOverlay->srcW2; + int srcH = pOverlay->srcH2; + CARD16 LCDheight = pSiS->LCDheight; + int srcPitch = pOverlay->origPitch; + int origdstH = dstH; + int modeflags = pOverlay->currentmode2->Flags; + + /* TW: Stretch image due to panel link scaling */ + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) { + if(pSiS->MiscFlags & MISC_PANELLINKSCALER) { + dstH = (dstH * LCDheight) / pOverlay->SCREENheight2; + flag = 1; } - else if (dstH > srcH) { - dstH += 0x02; - pOverlay->VUSF = (srcH << 16) / dstH; - pOverlay->IntBit |= 0x08; + } + } + /* TW: For double scan modes, we need to double the height + * On 315 and 550 (?), we need to double the width as well. + * Interlace mode vice versa. + */ + if(modeflags & V_DBLSCAN) { + dstH = origdstH << 1; + flag = 0; + if((pSiS->sishw_ext.jChipType >= SIS_315H) && + (pSiS->sishw_ext.jChipType <= SIS_550)) { + dstW <<= 1; + } + } + if(modeflags & V_INTERLACE) { + dstH = origdstH >> 1; + flag = 0; + } + +#if 0 + /* TEST @@@ */ + if(pOverlay->bobEnable & 0x08) dstH <<= 1; +#endif + + if(dstW < OVERLAY_MIN_WIDTH) dstW = OVERLAY_MIN_WIDTH; + if (dstW == srcW) { + pOverlay->HUSF2 = 0x00; + pOverlay->IntBit2 = 0x05; + pOverlay->wHPre2 = 0; + } else if (dstW > srcW) { + dstW += 2; + pOverlay->HUSF2 = (srcW << 16) / dstW; + pOverlay->IntBit2 = 0x04; + pOverlay->wHPre2 = 0; + } else { + int tmpW = dstW; + + /* TW: It seems, the hardware can't scale below factor .125 (=1/8) if the + pitch isn't a multiple of 256. + TODO: Test this on the 315 series! + */ + if((srcPitch % 256) || (srcPitch < 256)) { + if(((dstW * 1000) / srcW) < 125) dstW = tmpW = ((srcW * 125) / 1000) + 1; } - else { - CARD32 realI; - I = realI = srcH / dstH; - pOverlay->IntBit |= 0x02; + I = 0; + pOverlay->IntBit2 = 0x01; + while (srcW >= tmpW) { + tmpW <<= 1; + I++; + } + pOverlay->wHPre2 = (CARD8)(I - 1); + dstW <<= (I - 1); + if ((srcW % dstW)) + pOverlay->HUSF2 = ((srcW - dstW) << 16) / dstW; + else + pOverlay->HUSF2 = 0x00; + } - if (I < 2) - { - pOverlay->VUSF = ((srcH - dstH)<<16)/dstH; - } - else - { + if(dstH < OVERLAY_MIN_HEIGHT) dstH = OVERLAY_MIN_HEIGHT; + if(dstH == srcH) { + pOverlay->VUSF2 = 0x00; + pOverlay->IntBit2 |= 0x0A; + } else if(dstH > srcH) { + dstH += 0x02; + pOverlay->VUSF2 = (srcH << 16) / dstH; + pOverlay->IntBit2 |= 0x08; + } else { + CARD32 realI; + + I = realI = srcH / dstH; + pOverlay->IntBit2 |= 0x02; + + if(I < 2) { + pOverlay->VUSF2 = ((srcH - dstH) << 16) / dstH; + /* TW: Needed for LCD-scaling modes */ + if(flag && ((mult = (srcH / origdstH)) >= 2)) + pOverlay->pitch2 /= mult; + } else { #if 0 - if (((pOverlay->bobEnable & 0x08) == 0x00) && - (((srcPitch * I)>>2) > 0xFFF)) - { - pOverlay->bobEnable |= 0x08; - srcPitch >>= 1; - } -#endif - if (((srcPitch * I)>>2) > 0xFFF) - { - I = (0xFFF*2/srcPitch); - pOverlay->VUSF = 0xFFFF; - } - else - { - dstH = I * dstH; - if (srcH % dstH) - pOverlay->VUSF = ((srcH - dstH) << 16) / dstH; - else - pOverlay->VUSF = 0x00; - } - /* set video frame buffer offset */ - pOverlay->pitch = (CARD16)(srcPitch*I); - } - } + if (((pOverlay->bobEnable & 0x08) == 0x00) && + (((srcPitch * I)>>2) > 0xFFF)){ + pOverlay->bobEnable |= 0x08; + srcPitch >>= 1; + } +#endif + if (((srcPitch * I)>>2) > 0xFFF) { + I = (0xFFF*2/srcPitch); + pOverlay->VUSF2 = 0xFFFF; + } else { + dstH = I * dstH; + if (srcH % dstH) + pOverlay->VUSF2 = ((srcH - dstH) << 16) / dstH; + else + pOverlay->VUSF2 = 0x00; + } + /* set video frame buffer offset */ + pOverlay->pitch2 = (CARD16)(srcPitch*I); + } + } +} +#endif + +static CARD8 +calc_line_buf_size(CARD32 srcW, CARD8 wHPre, CARD32 pixelFormat) +{ + CARD8 preHIDF; + CARD32 I; + CARD32 line = srcW; + + if ( (pixelFormat == PIXEL_FMT_YV12) || + (pixelFormat == PIXEL_FMT_I420) || + (pixelFormat == PIXEL_FMT_NV12) || + (pixelFormat == PIXEL_FMT_NV21) ) + { + preHIDF = wHPre & 0x07; + switch (preHIDF) + { + case 3 : + if ((line & 0xffffff00) == line) + I = (line >> 8); + else + I = (line >> 8) + 1; + return((CARD8)(I * 32 - 1)); + case 4 : + if ((line & 0xfffffe00) == line) + I = (line >> 9); + else + I = (line >> 9) + 1; + return((CARD8)(I * 64 - 1)); + case 5 : + if ((line & 0xfffffc00) == line) + I = (line >> 10); + else + I = (line >> 10) + 1; + return((CARD8)(I * 128 - 1)); + case 6 : + return((CARD8)(255)); + default : + if ((line & 0xffffff80) == line) + I = (line >> 7); + else + I = (line >> 7) + 1; + return((CARD8)(I * 16 - 1)); + } + } else { /* YUV2, UYVY */ + if ((line & 0xffffff8) == line) + I = (line >> 3); + else + I = (line >> 3) + 1; + return((CARD8)(I - 1)); + } +} + +static __inline void +set_line_buf_size_1(SISOverlayPtr pOverlay) +{ + pOverlay->lineBufSize = calc_line_buf_size(pOverlay->srcW,pOverlay->wHPre, pOverlay->pixelFormat); } +#ifdef SISMERGED +static __inline void +set_line_buf_size_2(SISOverlayPtr pOverlay) +{ + pOverlay->lineBufSize2 = calc_line_buf_size(pOverlay->srcW2,pOverlay->wHPre2, pOverlay->pixelFormat); +} static void -set_line_buf_size(SISOverlayPtr pOverlay) -{ - CARD8 preHIDF; - CARD32 I; - CARD32 line = pOverlay->srcW; - - if (pOverlay->pixelFormat == PIXEL_FMT_YV12) - { - preHIDF = pOverlay->wHPre & 0x07; - switch (preHIDF) - { - case 3 : - if ((line & 0xffffff00) == line) - I = (line >> 8); - else - I = (line >> 8) + 1; - pOverlay->lineBufSize = (CARD8)(I * 32 - 1); - break; - case 4 : - if ((line & 0xfffffe00) == line) - I = (line >> 9); - else - I = (line >> 9) + 1; - pOverlay->lineBufSize = (CARD8)(I * 64 - 1); - break; - case 5 : - if ((line & 0xfffffc00) == line) - I = (line >> 10); - else - I = (line >> 10) + 1; - pOverlay->lineBufSize = (CARD8)(I * 128 - 1); - break; - case 6 : - if ((line & 0xfffff800) == line) - I = (line >> 11); - else - I = (line >> 11) + 1; - pOverlay->lineBufSize = (CARD8)(I * 256 - 1); - break; - default : - if ((line & 0xffffff80) == line) - I = (line >> 7); - else - I = (line >> 7) + 1; - pOverlay->lineBufSize = (CARD8)(I * 16 - 1); - break; - } - } - else - { - if ((line & 0xffffff8) == line) - I = (line >> 3); - else - I = (line >> 3) + 1; - pOverlay->lineBufSize = (CARD8)(I - 1); - } +merge_line_buf_mfb(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable1, Bool enable2, + short width1, short width2, short limit) +{ + unsigned char misc1, misc2, mask = pPriv->linebufmask; + + if(pPriv->hasTwoOverlays) { /* This means we are in MIRROR mode */ + + misc2 = 0x00; + if(enable1) misc1 = 0x04; + else misc1 = 0x00; + setvideoregmask(pSiS, Index_VI_Control_Misc2, misc2, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, misc1, 0x04); + + misc2 = 0x01; + if(enable2) misc1 = 0x04; + else misc1 = 0x00; + setvideoregmask(pSiS, Index_VI_Control_Misc2, misc2, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, misc1, 0x04); + + } else { /* This means we are either in SINGLE1 or SINGLE2 mode */ + + misc2 = 0x00; + if(enable1 || enable2) misc1 = 0x04; + else misc1 = 0x00; + + setvideoregmask(pSiS, Index_VI_Control_Misc2, misc2, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, misc1, 0x04); + + } } +#endif + +/* About linebuffer merging: + * + * For example the 651: + * Each overlay has 4 line buffers, 384 bytes each (<-- Is that really correct? 1920 / 384 = 5 !!!) + * If the source width is greater than 384, line buffers must be merged. + * Dual merge: Only O1 usable (uses overlay 2's linebuffer), maximum width 384*2 + * Individual merge: Both overlays available, maximum width 384*2 + * All merge: Only overlay 1 available, maximum width = 384*4 (<--- should be 1920, is 1536...) + * + * + * Normally: Dual merge: Individual merge + * Overlay 1 Overlay 2 Overlay 1 only! Both overlays + * ___1___ ___5___ ___1___ ___2___ -\ O1 ___1___ ___2___ + * ___2___ ___6___ ___3___ ___4___ \_ O 1 O1 ___3___ ___4___ + * ___3___ ___7___ ___5___ ___6___ / O2 ___5___ ___6___ + * ___4___ ___8___ ___7___ ___8___ -/ O2 ___7___ ___8___ + * + * + * All merge: ___1___ ___2___ ___3___ ___4___ + * (Overlay 1 only!) ___5___ ___6___ ___7___ ___8___ + * + * Individual merge is supported on all chipsets. + * Dual merge is only supported on the 300 series and M650/651 and later. + * All merge is only supported on the M650/651 and later. + * + */ + static void -merge_line_buf(SISPtr pSIS, SISPortPrivPtr pPriv, Bool enable) -{ - if(enable) { - if(pPriv->displayMode == DISPMODE_MIRROR) { - setvideoregmask(pSIS, Index_VI_Control_Misc2, 0x00, 0x11); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x04, 0x04); - setvideoregmask(pSIS, Index_VI_Control_Misc2, 0x01, 0x11); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x04, 0x04); +merge_line_buf(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable, short width, short limit) +{ + unsigned char misc1, misc2, mask = pPriv->linebufmask; + + if(enable) { /* ----- enable linebuffer merge */ + + switch(pPriv->displayMode){ + case DISPMODE_SINGLE1: + if(pSiS->VGAEngine == SIS_300_VGA) { + if(pPriv->dualHeadMode) { + misc2 = 0x00; + misc1 = 0x04; + } else { + misc2 = 0x10; + misc1 = 0x00; + } + } else { + if(pPriv->hasTwoOverlays) { + if(pPriv->dualHeadMode) { + misc2 = 0x00; + misc1 = 0x04; + } else { + if(width > (limit * 2)) { + misc2 = 0x20; + } else { + misc2 = 0x10; + } + misc1 = 0x00; + } + } else { + misc2 = 0x00; + misc1 = 0x04; + } + } + setvideoregmask(pSiS, Index_VI_Control_Misc2, misc2, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, misc1, 0x04); + break; + + case DISPMODE_SINGLE2: + if(pSiS->VGAEngine == SIS_300_VGA) { + if(pPriv->dualHeadMode) { + misc2 = 0x01; + misc1 = 0x04; + } else { + misc2 = 0x10; + misc1 = 0x00; + } + } else { + if(pPriv->hasTwoOverlays) { + if(pPriv->dualHeadMode) { + misc2 = 0x01; + misc1 = 0x04; + } else { + if(width > (limit * 2)) { + misc2 = 0x20; + } else { + misc2 = 0x10; + } + misc1 = 0x00; + } + } else { + misc2 = 0x00; + misc1 = 0x04; + } + } + setvideoregmask(pSiS, Index_VI_Control_Misc2, misc2, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, misc1, 0x04); + break; + + case DISPMODE_MIRROR: /* This can only be on chips with 2 overlays */ + default: + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x04, 0x04); + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x04, 0x04); + break; } - else { - setvideoregmask(pSIS, Index_VI_Control_Misc2, 0x10, 0x11); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x00, 0x04); - setvideoregmask(pSIS, Index_VI_Control_Misc2, 0x11, 0x11); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x00, 0x04); + + } else { /* ----- disable linebuffer merge */ + + switch(pPriv->displayMode) { + + case DISPMODE_SINGLE1: + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04); + break; + + case DISPMODE_SINGLE2: + if(pSiS->VGAEngine == SIS_300_VGA) { + if(pPriv->dualHeadMode) misc2 = 0x01; + else misc2 = 0x00; + } else { + if(pPriv->hasTwoOverlays) { + if(pPriv->dualHeadMode) misc2 = 0x01; + else misc2 = 0x00; + } else { + misc2 = 0x00; + } + } + setvideoregmask(pSiS, Index_VI_Control_Misc2, misc2, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04); + break; + + case DISPMODE_MIRROR: /* This can only be on chips with 2 overlays */ + default: + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04); + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, mask); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04); + break; } } - else { - setvideoregmask(pSIS, Index_VI_Control_Misc2, 0x00, 0x11); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x00, 0x04); - setvideoregmask(pSIS, Index_VI_Control_Misc2, 0x01, 0x11); - setvideoregmask(pSIS, Index_VI_Control_Misc1, 0x00, 0x04); - } } +static __inline void +set_format(SISPtr pSiS, SISOverlayPtr pOverlay) +{ + CARD8 fmt; -static void -set_format(SISPtr pSIS, SISOverlayPtr pOverlay) -{ - CARD8 fmt; - - switch (pOverlay->pixelFormat) - { - case PIXEL_FMT_YV12: - fmt = 0x0c; - break; - case PIXEL_FMT_YUY2: - fmt = 0x28; - break; - default: - fmt = 0x00; - break; - } - setvideoregmask(pSIS, Index_VI_Control_Misc0, fmt, 0x7c); + switch (pOverlay->pixelFormat){ + case PIXEL_FMT_YV12: + case PIXEL_FMT_I420: + fmt = 0x0c; + break; + case PIXEL_FMT_YUY2: + fmt = 0x28; + break; + case PIXEL_FMT_UYVY: + fmt = 0x08; + break; + case PIXEL_FMT_YVYU: + fmt = 0x38; + break; + case PIXEL_FMT_NV12: + fmt = 0x4c; + break; + case PIXEL_FMT_NV21: + fmt = 0x5c; + break; + case PIXEL_FMT_RGB5: /* D[5:4] : 00 RGB555, 01 RGB 565 */ + fmt = 0x00; + break; + case PIXEL_FMT_RGB6: + fmt = 0x10; + break; + default: + fmt = 0x00; + break; + } + setvideoregmask(pSiS, Index_VI_Control_Misc0, fmt, 0xfc); } -static void -set_colorkey(SISPtr pSIS, CARD32 colorkey) +static __inline void +set_colorkey(SISPtr pSiS, CARD32 colorkey) { - CARD8 r, g, b; + CARD8 r, g, b; + + b = (CARD8)(colorkey & 0xFF); + g = (CARD8)((colorkey>>8) & 0xFF); + r = (CARD8)((colorkey>>16) & 0xFF); - b = (CARD8)(colorkey & 0xFF); - g = (CARD8)((colorkey>>8) & 0xFF); - r = (CARD8)((colorkey>>16) & 0xFF); + setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Blue_Min ,(CARD8)b); + setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Green_Min ,(CARD8)g); + setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Red_Min ,(CARD8)r); - /* Activate the colorkey mode */ - setvideoreg(pSIS, Index_VI_Overlay_ColorKey_Blue_Min ,(CARD8)b); - setvideoreg(pSIS, Index_VI_Overlay_ColorKey_Green_Min ,(CARD8)g); - setvideoreg(pSIS, Index_VI_Overlay_ColorKey_Red_Min ,(CARD8)r); + setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Blue_Max ,(CARD8)b); + setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Green_Max ,(CARD8)g); + setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Red_Max ,(CARD8)r); +} - setvideoreg(pSIS, Index_VI_Overlay_ColorKey_Blue_Max ,(CARD8)b); - setvideoreg(pSIS, Index_VI_Overlay_ColorKey_Green_Max ,(CARD8)g); - setvideoreg(pSIS, Index_VI_Overlay_ColorKey_Red_Max ,(CARD8)r); +static __inline void +set_chromakey(SISPtr pSiS, CARD32 chromamin, CARD32 chromamax) +{ + CARD8 r1, g1, b1; + CARD8 r2, g2, b2; + + b1 = (CARD8)(chromamin & 0xFF); + g1 = (CARD8)((chromamin>>8) & 0xFF); + r1 = (CARD8)((chromamin>>16) & 0xFF); + b2 = (CARD8)(chromamax & 0xFF); + g2 = (CARD8)((chromamax>>8) & 0xFF); + r2 = (CARD8)((chromamax>>16) & 0xFF); + + setvideoreg(pSiS, Index_VI_Overlay_ChromaKey_Blue_V_Min ,(CARD8)b1); + setvideoreg(pSiS, Index_VI_Overlay_ChromaKey_Green_U_Min ,(CARD8)g1); + setvideoreg(pSiS, Index_VI_Overlay_ChromaKey_Red_Y_Min ,(CARD8)r1); + + setvideoreg(pSiS, Index_VI_Overlay_ChromaKey_Blue_V_Max ,(CARD8)b2); + setvideoreg(pSiS, Index_VI_Overlay_ChromaKey_Green_U_Max ,(CARD8)g2); + setvideoreg(pSiS, Index_VI_Overlay_ChromaKey_Red_Y_Max ,(CARD8)r2); } +static __inline void +set_brightness(SISPtr pSiS, CARD8 brightness) +{ + setvideoreg(pSiS, Index_VI_Brightness, brightness); +} -static void -set_brightness(SISPtr pSIS, CARD8 brightness) +static __inline void +set_contrast(SISPtr pSiS, CARD8 contrast) { - setvideoreg(pSIS, Index_VI_Brightness ,brightness); + setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, contrast, 0x07); } +/* 315 series and later only */ +static __inline void +set_saturation(SISPtr pSiS, char saturation) +{ + CARD8 temp = 0; + + if(saturation < 0) { + temp |= 0x88; + saturation = -saturation; + } + temp |= (saturation & 0x07); + temp |= ((saturation & 0x07) << 4); + + setvideoreg(pSiS, Index_VI_Saturation, temp); +} + +/* 315 series and later only */ +static __inline void +set_hue(SISPtr pSiS, CARD8 hue) +{ + setvideoreg(pSiS, Index_VI_Hue, (hue & 0x08) ? (hue ^ 0x07) : hue); +} + +static __inline void +set_disablegfx(SISPtr pSiS, Bool mybool, SISOverlayPtr pOverlay) +{ + /* This is not supported on M65x or 65x (x>0) */ + /* For CRT1 ONLY!!! */ + if(!(pSiS->ChipFlags & SiSCF_Is65x)) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, mybool ? 0x04 : 0x00, 0x04); + if(mybool) pOverlay->keyOP = VI_ROP_Always; + } +} + +static __inline void +set_disablegfxlr(SISPtr pSiS, Bool mybool, SISOverlayPtr pOverlay) +{ + setvideoregmask(pSiS, Index_VI_Control_Misc1, mybool ? 0x01 : 0x00, 0x01); + if(mybool) pOverlay->keyOP = VI_ROP_Always; +} + +#ifdef SIS_CP + SIS_CP_VIDEO_SUBS +#endif static void -set_overlay(SISPtr pSIS, SISOverlayPtr pOverlay) +set_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index, int iscrt2) { - ScrnInfoPtr pScrn = pSIS->pScrn; + ScrnInfoPtr pScrn = pSiS->pScrn; + + CARD16 pitch=0; + CARD8 h_over=0, v_over=0; + CARD16 top, bottom, left, right; + CARD16 screenX, screenY; + int modeflags; + CARD8 data; + CARD32 watchdog; + CARD32 PSY; + +#ifdef SISMERGED + if(pSiS->MergedFB && iscrt2) { + screenX = pOverlay->currentmode2->HDisplay; + screenY = pOverlay->currentmode2->VDisplay; + modeflags = pOverlay->currentmode2->Flags; + top = pOverlay->dstBox2.y1; + bottom = pOverlay->dstBox2.y2; + left = pOverlay->dstBox2.x1; + right = pOverlay->dstBox2.x2; + pitch = pOverlay->pitch2 >> pPriv->shiftValue; + } else { +#endif + screenX = pOverlay->currentmode->HDisplay; + screenY = pOverlay->currentmode->VDisplay; + modeflags = pOverlay->currentmode->Flags; + top = pOverlay->dstBox.y1; + bottom = pOverlay->dstBox.y2; + left = pOverlay->dstBox.x1; + right = pOverlay->dstBox.x2; + pitch = pOverlay->pitch >> pPriv->shiftValue; +#ifdef SISMERGED + } +#endif + + if(bottom > screenY) { + bottom = screenY; + } + if(right > screenX) { + right = screenX; + } + + /* TW: DoubleScan modes require Y coordinates * 2 */ + if(modeflags & V_DBLSCAN) { + top <<= 1; + bottom <<= 1; + } + /* TW: Interlace modes require Y coordinates / 2 */ + if(modeflags & V_INTERLACE) { + top >>= 1; + bottom >>= 1; + } + + h_over = (((left>>8) & 0x0f) | ((right>>4) & 0xf0)); + v_over = (((top>>8) & 0x0f) | ((bottom>>4) & 0xf0)); - CARD16 pitch=0; - CARD8 h_over=0, v_over=0; - CARD16 bottom, right; - CARD16 screenX = pScrn->currentMode->HDisplay; - CARD16 screenY = pScrn->currentMode->VDisplay; + /* set line buffer size */ +#ifdef SISMERGED + if(pSiS->MergedFB && iscrt2) + setvideoreg(pSiS, Index_VI_Line_Buffer_Size, pOverlay->lineBufSize2); + else +#endif + setvideoreg(pSiS, Index_VI_Line_Buffer_Size, pOverlay->lineBufSize); + + /* set color key mode */ + setvideoregmask(pSiS, Index_VI_Key_Overlay_OP, pOverlay->keyOP, 0x0f); + + /* We don't have to wait for vertical retrace in all cases */ + if(pPriv->mustwait) { + watchdog = WATCHDOG_DELAY; + while (pOverlay->VBlankActiveFunc(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while ((!pOverlay->VBlankActiveFunc(pSiS)) && --watchdog); + if (!watchdog) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Xv: Waiting for vertical retrace timed-out\n"); + } - bottom = pOverlay->dstBox.y2; - if (bottom > screenY) - bottom = screenY; + /* Unlock address registers */ + data = getvideoreg(pSiS, Index_VI_Control_Misc1); + setvideoreg(pSiS, Index_VI_Control_Misc1, data | 0x20); + /* Is this required? */ + setvideoreg(pSiS, Index_VI_Control_Misc1, data | 0x20); + + /* Is this required? (seems so) */ + if (pSiS->Chipset == SIS_315_VGA) + setvideoregmask(pSiS, Index_VI_Control_Misc3, 0x00, (1 << index)); + + /* Set Y buf pitch */ + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Pitch_Low, (CARD8)(pitch)); + setvideoregmask(pSiS, Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (CARD8)(pitch >> 8), 0x0f); + + /* Set Y start address */ +#ifdef SISMERGED + if(pSiS->MergedFB && iscrt2) { + PSY = pOverlay->PSY2; + } else +#endif + PSY = pOverlay->PSY; - right = pOverlay->dstBox.x2; - if (right > screenX) - right = screenX; + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Start_Low, (CARD8)(PSY)); + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Start_Middle, (CARD8)(PSY >> 8)); + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Start_High, (CARD8)(PSY >> 16)); - h_over = (((pOverlay->dstBox.x1>>8) & 0x0f) | ((right>>4) & 0xf0)); - v_over = (((pOverlay->dstBox.y1>>8) & 0x0f) | ((bottom>>4) & 0xf0)); + /* set 315 series overflow bits for Y plane */ + if (pSiS->VGAEngine == SIS_315_VGA) { + setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Pitch_High, (CARD8)(pitch >> 12)); + setvideoreg(pSiS, Index_VI_Y_Buf_Start_Over, ((CARD8)(PSY >> 24) & 0x03)); + } - pitch = pOverlay->pitch; + /* Set U/V data if using planar formats */ + if ( (pOverlay->pixelFormat == PIXEL_FMT_YV12) || + (pOverlay->pixelFormat == PIXEL_FMT_I420) || + (pOverlay->pixelFormat == PIXEL_FMT_NV12) || + (pOverlay->pixelFormat == PIXEL_FMT_NV21) ) { - /* set line buffer size */ - setvideoreg(pSIS, Index_VI_Line_Buffer_Size, pOverlay->lineBufSize); - - setvideoregmask (pSIS, Index_VI_Key_Overlay_OP, pOverlay->keyOP, 0x0f); + CARD32 PSU=0, PSV=0, uvpitch = pitch; - while (pOverlay->VBlankActiveFunc(pSIS)); - while (!pOverlay->VBlankActiveFunc(pSIS)); - - setvideoreg (pSIS, Index_VI_Disp_Y_Buf_Pitch_Low, (CARD8)(pitch>>2)); - setvideoregmask (pSIS, Index_VI_Disp_Y_UV_Buf_Pitch_High, (CARD8)(pitch >> 10), 0x0f); - - setvideoregmask (pSIS, Index_VI_Control_Misc1, 0x20, 0x20); - if (pOverlay->pixelFormat == PIXEL_FMT_YV12) - { - CARD32 PSU=0, PSV=0; - - PSU = pOverlay->PSU; - PSV = pOverlay->PSV; - - setvideoreg (pSIS, Index_VI_Disp_UV_Buf_Pitch_Low, (CARD8)(pitch >> 3)); - setvideoregmask (pSIS, Index_VI_Disp_Y_UV_Buf_Pitch_High, (CARD8)(pitch >> 7), 0xf0); - /* set U/V start address */ - setvideoreg (pSIS, Index_VI_U_Buf_Start_Low, (CARD8)PSU); - setvideoreg (pSIS, Index_VI_U_Buf_Start_Middle,(CARD8)(PSU>>8)); - setvideoreg (pSIS, Index_VI_U_Buf_Start_High, (CARD8)(PSU>>16)); - - setvideoreg (pSIS, Index_VI_V_Buf_Start_Low, (CARD8)PSV); - setvideoreg (pSIS, Index_VI_V_Buf_Start_Middle,(CARD8)(PSV>>8)); - setvideoreg (pSIS, Index_VI_V_Buf_Start_High, (CARD8)(PSV>>16)); + PSU = pOverlay->PSU; + PSV = pOverlay->PSV; +#ifdef SISMERGED + if(pSiS->MergedFB && iscrt2) { + PSU = pOverlay->PSU2; + PSV = pOverlay->PSV2; } - /* set scale factor */ - setvideoreg (pSIS, Index_VI_Hor_Post_Up_Scale_Low, (CARD8)(pOverlay->HUSF)); - setvideoreg (pSIS, Index_VI_Hor_Post_Up_Scale_High,(CARD8)((pOverlay->HUSF)>>8)); - setvideoreg (pSIS, Index_VI_Ver_Up_Scale_Low, (CARD8)(pOverlay->VUSF)); - setvideoreg (pSIS, Index_VI_Ver_Up_Scale_High, (CARD8)((pOverlay->VUSF)>>8)); - - setvideoregmask (pSIS, Index_VI_Scale_Control, (pOverlay->IntBit << 3)|(pOverlay->wHPre), 0x7f); - - /* set destination position */ - setvideoreg(pSIS, Index_VI_Win_Hor_Disp_Start_Low, (CARD8)pOverlay->dstBox.x1); - setvideoreg(pSIS, Index_VI_Win_Hor_Disp_End_Low, (CARD8)right); - setvideoreg(pSIS, Index_VI_Win_Hor_Over, (CARD8)h_over); - - setvideoreg(pSIS, Index_VI_Win_Ver_Disp_Start_Low, (CARD8)pOverlay->dstBox.y1); - setvideoreg(pSIS, Index_VI_Win_Ver_Disp_End_Low, (CARD8)bottom); - setvideoreg(pSIS, Index_VI_Win_Ver_Over, (CARD8)v_over); - - /* set display start address */ - setvideoreg (pSIS, Index_VI_Disp_Y_Buf_Start_Low, (CARD8)(pOverlay->PSY)); - setvideoreg (pSIS, Index_VI_Disp_Y_Buf_Start_Middle, (CARD8)((pOverlay->PSY)>>8)); - setvideoreg (pSIS, Index_VI_Disp_Y_Buf_Start_High, (CARD8)((pOverlay->PSY)>>16)); - setvideoregmask(pSIS, Index_VI_Control_Misc1, pOverlay->bobEnable, 0x1a); - setvideoregmask (pSIS, Index_VI_Control_Misc1, 0x00, 0x20); - - /* set contrast factor */ -/* - setvideoregmask(pSIS, Index_VI_Contrast_Enh_Ctrl, pOverlay->contrastCtrl<<6, 0xc0); - setvideoreg (pSIS, Index_VI_Contrast_Factor, pOverlay->contrastFactor); -*/ -} +#endif + if((pOverlay->pixelFormat == PIXEL_FMT_YV12) || + (pOverlay->pixelFormat == PIXEL_FMT_I420)) { + uvpitch >>= 1; + } + + /* Set U/V pitch */ + setvideoreg (pSiS, Index_VI_Disp_UV_Buf_Pitch_Low, (CARD8)uvpitch); + setvideoregmask (pSiS, Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (CARD8)(uvpitch >> 4), 0xf0); + + /* set U/V start address */ + setvideoreg (pSiS, Index_VI_U_Buf_Start_Low, (CARD8)PSU); + setvideoreg (pSiS, Index_VI_U_Buf_Start_Middle,(CARD8)(PSU >> 8)); + setvideoreg (pSiS, Index_VI_U_Buf_Start_High, (CARD8)(PSU >> 16)); + + setvideoreg (pSiS, Index_VI_V_Buf_Start_Low, (CARD8)PSV); + setvideoreg (pSiS, Index_VI_V_Buf_Start_Middle,(CARD8)(PSV >> 8)); + setvideoreg (pSiS, Index_VI_V_Buf_Start_High, (CARD8)(PSV >> 16)); + + /* 315 series overflow bits */ + if (pSiS->VGAEngine == SIS_315_VGA) { + setvideoreg (pSiS, Index_VI_Disp_UV_Buf_Pitch_High, (CARD8)(uvpitch >> 12)); + setvideoreg (pSiS, Index_VI_U_Buf_Start_Over, ((CARD8)(PSU >> 24) & 0x03)); + setvideoreg (pSiS, Index_VI_V_Buf_Start_Over, ((CARD8)(PSV >> 24) & 0x03)); + } + } + + /* set scale factor */ +#ifdef SISMERGED + if(pSiS->MergedFB && iscrt2) { + setvideoreg (pSiS, Index_VI_Hor_Post_Up_Scale_Low, (CARD8)(pOverlay->HUSF2)); + setvideoreg (pSiS, Index_VI_Hor_Post_Up_Scale_High,(CARD8)((pOverlay->HUSF2) >> 8)); + setvideoreg (pSiS, Index_VI_Ver_Up_Scale_Low, (CARD8)(pOverlay->VUSF2)); + setvideoreg (pSiS, Index_VI_Ver_Up_Scale_High, (CARD8)((pOverlay->VUSF2) >> 8)); + + setvideoregmask (pSiS, Index_VI_Scale_Control, (pOverlay->IntBit2 << 3) + |(pOverlay->wHPre2), 0x7f); + } else { +#endif + setvideoreg (pSiS, Index_VI_Hor_Post_Up_Scale_Low, (CARD8)(pOverlay->HUSF)); + setvideoreg (pSiS, Index_VI_Hor_Post_Up_Scale_High,(CARD8)((pOverlay->HUSF) >> 8)); + setvideoreg (pSiS, Index_VI_Ver_Up_Scale_Low, (CARD8)(pOverlay->VUSF)); + setvideoreg (pSiS, Index_VI_Ver_Up_Scale_High, (CARD8)((pOverlay->VUSF)>>8)); + + setvideoregmask (pSiS, Index_VI_Scale_Control, (pOverlay->IntBit << 3) + |(pOverlay->wHPre), 0x7f); +#ifdef SISMERGED + } +#endif + + /* set destination window position */ + setvideoreg(pSiS, Index_VI_Win_Hor_Disp_Start_Low, (CARD8)left); + setvideoreg(pSiS, Index_VI_Win_Hor_Disp_End_Low, (CARD8)right); + setvideoreg(pSiS, Index_VI_Win_Hor_Over, (CARD8)h_over); + + setvideoreg(pSiS, Index_VI_Win_Ver_Disp_Start_Low, (CARD8)top); + setvideoreg(pSiS, Index_VI_Win_Ver_Disp_End_Low, (CARD8)bottom); + setvideoreg(pSiS, Index_VI_Win_Ver_Over, (CARD8)v_over); + setvideoregmask(pSiS, Index_VI_Control_Misc1, pOverlay->bobEnable, 0x1a); + /* Lock the address registers */ + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x20); +} + +/* TW: Overlay MUST NOT be switched off while beam is over it */ static void -close_overlay(SISPtr pSIS, SISPortPrivPtr pPriv) +close_overlay(SISPtr pSiS, SISPortPrivPtr pPriv) { - setvideoregmask (pSIS, Index_VI_Control_Misc2, 0, 0x01); - setvideoregmask(pSIS, Index_VI_Control_Misc0, 0x00, 0x02); - setvideoregmask (pSIS, Index_VI_Control_Misc2, 1, 0x01); - setvideoregmask(pSIS, Index_VI_Control_Misc0, 0x00, 0x02); -} + CARD32 watchdog; + + if(!(pPriv->overlayStatus)) return; + pPriv->overlayStatus = FALSE; + + if(pPriv->displayMode & (DISPMODE_MIRROR | DISPMODE_SINGLE2)) { + + /* CRT2: MIRROR or SINGLE2 + * 1 overlay: Uses overlay 0 + * 2 overlays: Uses Overlay 1 if MIRROR or DUAL HEAD + * Uses Overlay 0 if SINGLE2 and not DUAL HEAD + */ + + if(pPriv->hasTwoOverlays) { + + if((pPriv->dualHeadMode) || (pPriv->displayMode == DISPMODE_MIRROR)) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x01); + } else { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x01); + } + + } else if(pPriv->displayMode == DISPMODE_SINGLE2) { + +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) { + /* Check if overlay already grabbed by other head */ + if(!(getsrreg(pSiS, 0x06) & 0x40)) return; + } +#endif + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x01); + + } + + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x01); + watchdog = WATCHDOG_DELAY; + while(vblank_active_CRT2(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT2(pSiS)) && --watchdog); + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + watchdog = WATCHDOG_DELAY; + while(vblank_active_CRT2(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT2(pSiS)) && --watchdog); + +#ifdef SIS_CP + SIS_CP_RESET_CP +#endif + + } + + if(pPriv->displayMode & (DISPMODE_SINGLE1 | DISPMODE_MIRROR)) { + /* CRT1: Always uses overlay 0 + */ + +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) { + if(!pPriv->hasTwoOverlays) { + /* Check if overlay already grabbed by other head */ + if(getsrreg(pSiS, 0x06) & 0x40) return; + } + } +#endif + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x05); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x01); + watchdog = WATCHDOG_DELAY; + while(vblank_active_CRT1(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT1(pSiS)) && --watchdog); + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + watchdog = WATCHDOG_DELAY; + while(vblank_active_CRT1(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT1(pSiS)) && --watchdog); + + } +} static void SISDisplayVideo(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) { - SISPtr pSIS = SISPTR(pScrn); - + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif short srcPitch = pPriv->srcPitch; short height = pPriv->height; + unsigned short screenwidth; SISOverlayRec overlay; int srcOffsetX=0, srcOffsetY=0; - int sx, sy; - int index = 0; + int sx=0, sy=0; + int index = 0, iscrt2 = 0; +#ifdef SISMERGED + unsigned char temp; + CARD32 watchdog; + unsigned short screen2width=0; + int srcOffsetX2=0, srcOffsetY2=0; + int sx2=0, sy2=0; +#endif + + pPriv->NoOverlay = FALSE; +#ifdef SISDUALHEAD + if(pPriv->dualHeadMode) { + if(!pPriv->hasTwoOverlays) { + if(pSiS->SecondHead) { + if(pSiSEnt->curxvcrtnum != 0) { + if(pPriv->overlayStatus) { + close_overlay(pSiS, pPriv); + } + pPriv->NoOverlay = TRUE; + return; + } + } else { + if(pSiSEnt->curxvcrtnum != 1) { + if(pPriv->overlayStatus) { + close_overlay(pSiS, pPriv); + } + pPriv->NoOverlay = TRUE; + return; + } + } + } + } +#endif + + /* TW: setup dispmode (MIRROR, SINGLEx) */ + set_dispmode(pScrn, pPriv); + + /* TW: Check if overlay is supported with current mode */ + if(pPriv->displayMode & (DISPMODE_SINGLE1 | DISPMODE_MIRROR)) { + if(!(pSiS->MiscFlags & MISC_CRT1OVERLAY)) { + if(pPriv->overlayStatus) { + close_overlay(pSiS, pPriv); + } + pPriv->NoOverlay = TRUE; + return; + } + } memset(&overlay, 0, sizeof(overlay)); + overlay.pixelFormat = pPriv->id; - overlay.pitch = srcPitch; - overlay.keyOP = 0x03; + overlay.pitch = overlay.origPitch = srcPitch; + if(pPriv->usechromakey) { + overlay.keyOP = (pPriv->insidechromakey) ? VI_ROP_ChromaKey : VI_ROP_NotChromaKey; + } else { + overlay.keyOP = VI_ROP_DestKey; + } /* overlay.bobEnable = 0x02; */ - overlay.bobEnable = 0x00; - - overlay.dstBox.x1 = pPriv->drw_x - pScrn->frameX0; - overlay.dstBox.x2 = pPriv->drw_x + pPriv->drw_w - pScrn->frameX0; - overlay.dstBox.y1 = pPriv->drw_y - pScrn->frameY0; - overlay.dstBox.y2 = pPriv->drw_y + pPriv->drw_h - pScrn->frameY0; + overlay.bobEnable = 0x00; /* Disable BOB de-interlacer */ + +#ifdef SISMERGED + if(pSiS->MergedFB) { + overlay.DoFirst = TRUE; + overlay.DoSecond = TRUE; + overlay.pitch2 = overlay.origPitch; + overlay.currentmode = ((SiSMergedDisplayModePtr)pSiS->CurrentLayout.mode->Private)->CRT1; + overlay.currentmode2 = ((SiSMergedDisplayModePtr)pSiS->CurrentLayout.mode->Private)->CRT2; + overlay.SCREENheight = overlay.currentmode->VDisplay; + overlay.SCREENheight2 = overlay.currentmode2->VDisplay; + screenwidth = overlay.currentmode->HDisplay; + screen2width = overlay.currentmode2->HDisplay; + overlay.dstBox.x1 = pPriv->drw_x - pSiS->CRT1frameX0; + overlay.dstBox.x2 = overlay.dstBox.x1 + pPriv->drw_w; + overlay.dstBox.y1 = pPriv->drw_y - pSiS->CRT1frameY0; + overlay.dstBox.y2 = overlay.dstBox.y1 + pPriv->drw_h; + overlay.dstBox2.x1 = pPriv->drw_x - pSiS->CRT2pScrn->frameX0; + overlay.dstBox2.x2 = overlay.dstBox2.x1 + pPriv->drw_w; + overlay.dstBox2.y1 = pPriv->drw_y - pSiS->CRT2pScrn->frameY0; + overlay.dstBox2.y2 = overlay.dstBox2.y1 + pPriv->drw_h; + /* xf86DrvMsg(0, X_INFO, "DV(1): %d %d %d %d | %d %d %d %d\n", + overlay.dstBox.x1,overlay.dstBox.x2,overlay.dstBox.y1,overlay.dstBox.y2, + overlay.dstBox2.x1,overlay.dstBox2.x2,overlay.dstBox2.y1,overlay.dstBox2.y2); */ + } else { +#endif + overlay.currentmode = pSiS->CurrentLayout.mode; + overlay.SCREENheight = overlay.currentmode->VDisplay; + screenwidth = overlay.currentmode->HDisplay; + overlay.dstBox.x1 = pPriv->drw_x - pScrn->frameX0; + overlay.dstBox.x2 = pPriv->drw_x + pPriv->drw_w - pScrn->frameX0; + overlay.dstBox.y1 = pPriv->drw_y - pScrn->frameY0; + overlay.dstBox.y2 = pPriv->drw_y + pPriv->drw_h - pScrn->frameY0; +#ifdef SISMERGED + } +#endif - /* FIXME: assume (x2 > x1), (y2 > y1) */ - if((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0)) - return; + if((overlay.dstBox.x1 > overlay.dstBox.x2) || + (overlay.dstBox.y1 > overlay.dstBox.y2)) { +#ifdef SISMERGED + if(pSiS->MergedFB) overlay.DoFirst = FALSE; + else +#endif + return; + } + + if((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0)) { +#ifdef SISMERGED + if(pSiS->MergedFB) overlay.DoFirst = FALSE; + else +#endif + return; + } + + if((overlay.dstBox.x1 >= screenwidth) || (overlay.dstBox.y1 >= overlay.SCREENheight)) { +#ifdef SISMERGED + if(pSiS->MergedFB) overlay.DoFirst = FALSE; + else +#endif + return; + } if(overlay.dstBox.x1 < 0) { - srcOffsetX = pPriv->src_w * (-overlay.dstBox.x1) / pPriv->drw_w; - overlay.dstBox.x1 = 0; + srcOffsetX = pPriv->src_w * (-overlay.dstBox.x1) / pPriv->drw_w; + overlay.dstBox.x1 = 0; } if(overlay.dstBox.y1 < 0) { - srcOffsetY = pPriv->src_h * (-overlay.dstBox.y1) / pPriv->drw_h; - overlay.dstBox.y1 = 0; + srcOffsetY = pPriv->src_h * (-overlay.dstBox.y1) / pPriv->drw_h; + overlay.dstBox.y1 = 0; } - switch(pPriv->id){ +#ifdef SISMERGED + if(pSiS->MergedFB) { + if((overlay.dstBox2.x1 > overlay.dstBox2.x2) || + (overlay.dstBox2.y1 > overlay.dstBox2.y2)) + overlay.DoSecond = FALSE; + + if((overlay.dstBox2.x2 < 0) || (overlay.dstBox2.y2 < 0)) + overlay.DoSecond = FALSE; + + if((overlay.dstBox2.x1 >= screen2width) || (overlay.dstBox2.y1 >= overlay.SCREENheight2)) + overlay.DoSecond = FALSE; + + if(overlay.dstBox2.x1 < 0) { + srcOffsetX2 = pPriv->src_w * (-overlay.dstBox2.x1) / pPriv->drw_w; + overlay.dstBox2.x1 = 0; + } + if(overlay.dstBox2.y1 < 0) { + srcOffsetY2 = pPriv->src_h * (-overlay.dstBox2.y1) / pPriv->drw_h; + overlay.dstBox2.y1 = 0; + } + + /* If neither overlay is to be displayed, disable them if they are currently enabled */ + if((!overlay.DoFirst) && (!overlay.DoSecond)) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x05); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x01); + temp = getvideoreg(pSiS,Index_VI_Control_Misc0); + if(temp & 0x02) { + watchdog = WATCHDOG_DELAY; + if(pPriv->hasTwoOverlays) { + while(vblank_active_CRT1(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT1(pSiS)) && --watchdog); + } else { + temp = getsrreg(pSiS, 0x06); + if(!(temp & 0x40)) { + while(vblank_active_CRT1(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT1(pSiS)) && --watchdog); + } else { + while(vblank_active_CRT2(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT2(pSiS)) && --watchdog); + } + } + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + } + if(pPriv->hasTwoOverlays) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x01); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x01); + temp = getvideoreg(pSiS,Index_VI_Control_Misc0); + if(temp & 0x02) { + watchdog = WATCHDOG_DELAY; + while(vblank_active_CRT2(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT2(pSiS)) && --watchdog); + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + } + } + pPriv->overlayStatus = FALSE; + return; + } + } +#endif + + /* xf86DrvMsg(0, X_INFO, "DV(2): %d %d %d %d | %d %d %d %d\n", + overlay.dstBox.x1,overlay.dstBox.x2,overlay.dstBox.y1,overlay.dstBox.y2, + overlay.dstBox2.x1,overlay.dstBox2.x2,overlay.dstBox2.y1,overlay.dstBox2.y2); */ + + switch(pPriv->id) { + case PIXEL_FMT_YV12: - sx = (pPriv->src_x + srcOffsetX) & ~7; - sy = (pPriv->src_y + srcOffsetY) & ~1; - overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch; - overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1); - overlay.PSU = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx + sy*srcPitch/2) >> 1); - overlay.PSY >>= 2; - overlay.PSV >>= 2; - overlay.PSU >>= 2; +#ifdef SISMERGED + if((!pSiS->MergedFB) || (overlay.DoFirst)) { +#endif + sx = (pPriv->src_x + srcOffsetX) & ~7; + sy = (pPriv->src_y + srcOffsetY) & ~1; + overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch; + overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1); + overlay.PSU = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx + sy*srcPitch/2) >> 1); +#ifdef SISDUALHEAD + overlay.PSY += HEADOFFSET; + overlay.PSV += HEADOFFSET; + overlay.PSU += HEADOFFSET; +#endif + overlay.PSY >>= pPriv->shiftValue; + overlay.PSV >>= pPriv->shiftValue; + overlay.PSU >>= pPriv->shiftValue; +#ifdef SISMERGED + } + if((pSiS->MergedFB) && (overlay.DoSecond)) { + sx2 = (pPriv->src_x + srcOffsetX2) & ~7; + sy2 = (pPriv->src_y + srcOffsetY2) & ~1; + overlay.PSY2 = pPriv->bufAddr[pPriv->currentBuf] + sx2 + sy2*srcPitch; + overlay.PSV2 = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx2 + sy2*srcPitch/2) >> 1); + overlay.PSU2 = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx2 + sy2*srcPitch/2) >> 1); + overlay.PSY2 >>= pPriv->shiftValue; + overlay.PSV2 >>= pPriv->shiftValue; + overlay.PSU2 >>= pPriv->shiftValue; + } +#endif + break; + + case PIXEL_FMT_I420: +#ifdef SISMERGED + if((!pSiS->MergedFB) || (overlay.DoFirst)) { +#endif + sx = (pPriv->src_x + srcOffsetX) & ~7; + sy = (pPriv->src_y + srcOffsetY) & ~1; + overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch; + overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx + sy*srcPitch/2) >> 1); + overlay.PSU = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1); +#ifdef SISDUALHEAD + overlay.PSY += HEADOFFSET; + overlay.PSV += HEADOFFSET; + overlay.PSU += HEADOFFSET; +#endif + overlay.PSY >>= pPriv->shiftValue; + overlay.PSV >>= pPriv->shiftValue; + overlay.PSU >>= pPriv->shiftValue; +#ifdef SISMERGED + } + if((pSiS->MergedFB) && (overlay.DoSecond)) { + sx2 = (pPriv->src_x + srcOffsetX2) & ~7; + sy2 = (pPriv->src_y + srcOffsetY2) & ~1; + overlay.PSY2 = pPriv->bufAddr[pPriv->currentBuf] + sx2 + sy2*srcPitch; + overlay.PSV2 = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx2 + sy2*srcPitch/2) >> 1); + overlay.PSU2 = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx2 + sy2*srcPitch/2) >> 1); + overlay.PSY2 >>= pPriv->shiftValue; + overlay.PSV2 >>= pPriv->shiftValue; + overlay.PSU2 >>= pPriv->shiftValue; + } +#endif + break; + + case PIXEL_FMT_NV12: + case PIXEL_FMT_NV21: +#ifdef SISMERGED + if((!pSiS->MergedFB) || (overlay.DoFirst)) { +#endif + sx = (pPriv->src_x + srcOffsetX) & ~7; + sy = (pPriv->src_y + srcOffsetY) & ~1; + overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch; + overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1); +#ifdef SISDUALHEAD + overlay.PSY += HEADOFFSET; + overlay.PSV += HEADOFFSET; +#endif + overlay.PSY >>= pPriv->shiftValue; + overlay.PSV >>= pPriv->shiftValue; + overlay.PSU = overlay.PSV; +#ifdef SISMERGED + } + if((pSiS->MergedFB) && (overlay.DoSecond)) { + sx2 = (pPriv->src_x + srcOffsetX2) & ~7; + sy2 = (pPriv->src_y + srcOffsetY2) & ~1; + overlay.PSY2 = pPriv->bufAddr[pPriv->currentBuf] + sx2 + sy2*srcPitch; + overlay.PSV2 = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx2 + sy2*srcPitch/2) >> 1); + overlay.PSY2 >>= pPriv->shiftValue; + overlay.PSV2 >>= pPriv->shiftValue; + overlay.PSU2 = overlay.PSV2; + } +#endif break; + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_YVYU: + case PIXEL_FMT_RGB6: + case PIXEL_FMT_RGB5: default: - sx = (pPriv->src_x + srcOffsetX) & ~1; - sy = (pPriv->src_y + srcOffsetY); - overlay.PSY = (pPriv->bufAddr[pPriv->currentBuf] + sx*2 + sy*srcPitch) >> 2; - break; +#ifdef SISMERGED + if((!pSiS->MergedFB) || (overlay.DoFirst)) { +#endif + sx = (pPriv->src_x + srcOffsetX) & ~1; + sy = (pPriv->src_y + srcOffsetY); + overlay.PSY = (pPriv->bufAddr[pPriv->currentBuf] + sx*2 + sy*srcPitch); +#ifdef SISDUALHEAD + overlay.PSY += HEADOFFSET; +#endif + overlay.PSY >>= pPriv->shiftValue; +#ifdef SISMERGED + } + if((pSiS->MergedFB) && (overlay.DoSecond)) { + sx2 = (pPriv->src_x + srcOffsetX2) & ~1; + sy2 = (pPriv->src_y + srcOffsetY2); + overlay.PSY2 = (pPriv->bufAddr[pPriv->currentBuf] + sx2*2 + sy2*srcPitch); + overlay.PSY2 >>= pPriv->shiftValue; + } +#endif + break; } - /* FIXME: is it possible that srcW < 0 */ - overlay.srcW = pPriv->src_w - (sx - pPriv->src_x); - overlay.srcH = pPriv->src_h - (sy - pPriv->src_y); - - /* merge line buffer */ - /* TODO: unnecessay to do it several times */ - merge_line_buf (pSIS, pPriv, (overlay.srcW > 384)); + /* Some clipping checks */ +#ifdef SISMERGED + if((!pSiS->MergedFB) || (overlay.DoFirst)) { +#endif + overlay.srcW = pPriv->src_w - (sx - pPriv->src_x); + overlay.srcH = pPriv->src_h - (sy - pPriv->src_y); + if( (pPriv->oldx1 != overlay.dstBox.x1) || + (pPriv->oldx2 != overlay.dstBox.x2) || + (pPriv->oldy1 != overlay.dstBox.y1) || + (pPriv->oldy2 != overlay.dstBox.y2) ) { + pPriv->mustwait = 1; + pPriv->oldx1 = overlay.dstBox.x1; pPriv->oldx2 = overlay.dstBox.x2; + pPriv->oldy1 = overlay.dstBox.y1; pPriv->oldy2 = overlay.dstBox.y2; + } +#ifdef SISMERGED + } + if((pSiS->MergedFB) && (overlay.DoSecond)) { + overlay.srcW2 = pPriv->src_w - (sx2 - pPriv->src_x); + overlay.srcH2 = pPriv->src_h - (sy2 - pPriv->src_y); + if( (pPriv->oldx1_2 != overlay.dstBox2.x1) || + (pPriv->oldx2_2 != overlay.dstBox2.x2) || + (pPriv->oldy1_2 != overlay.dstBox2.y1) || + (pPriv->oldy2_2 != overlay.dstBox2.y2) ) { + pPriv->mustwait = 1; + pPriv->oldx1_2 = overlay.dstBox2.x1; pPriv->oldx2_2 = overlay.dstBox2.x2; + pPriv->oldy1_2 = overlay.dstBox2.y1; pPriv->oldy2_2 = overlay.dstBox2.y2; + } + } +#endif - /* set line buffer length */ - set_line_buf_size (&overlay); - - /* set scale factor */ - set_scale_factor (&overlay); +#ifdef SISMERGED + /* Disable an overlay if it is not to be displayed (but enabled currently) */ + if((pSiS->MergedFB) && (pPriv->hasTwoOverlays)) { + if(!overlay.DoFirst) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x05); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x01); + temp = getvideoreg(pSiS,Index_VI_Control_Misc0); + if(temp & 0x02) { + watchdog = WATCHDOG_DELAY; + while(vblank_active_CRT1(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT1(pSiS)) && --watchdog); + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + } + } else if(!overlay.DoSecond) { + setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x01); + setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x01); + temp = getvideoreg(pSiS,Index_VI_Control_Misc0); + if(temp & 0x02) { + watchdog = WATCHDOG_DELAY; + while(vblank_active_CRT2(pSiS) && --watchdog); + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT2(pSiS)) && --watchdog); + setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02); + } + } + } +#endif - if(pPriv->displayMode == DISPMODE_SINGLE2) { - index = 1; - overlay.VBlankActiveFunc = vblank_active_CRT2; - overlay.GetScanLineFunc = get_scanline_CRT2; + /* Loop head */ + if(pPriv->displayMode & DISPMODE_SINGLE2) { + if(pPriv->hasTwoOverlays) { /* We have 2 overlays: */ + if(pPriv->dualHeadMode) { + /* Dual head: We use overlay 2 for CRT2 */ + index = 1; iscrt2 = 1; + } else { + /* Single head: We use overlay 1 for CRT2 */ + index = 0; iscrt2 = 1; + } + } else { /* We have 1 overlay */ + /* We use that only overlay for CRT2 */ + index = 0; iscrt2 = 1; + } + overlay.VBlankActiveFunc = vblank_active_CRT2; +#ifdef SISMERGED + if(!pPriv->hasTwoOverlays) { + if((pSiS->MergedFB) && (!overlay.DoSecond)) { + index = 0; iscrt2 = 0; + overlay.VBlankActiveFunc = vblank_active_CRT1; + pPriv->displayMode = DISPMODE_SINGLE1; + } + } +#endif + } else { + index = 0; iscrt2 = 0; + overlay.VBlankActiveFunc = vblank_active_CRT1; +#ifdef SISMERGED + if((pSiS->MergedFB) && (!overlay.DoFirst)) { + if(pPriv->hasTwoOverlays) index = 1; + iscrt2 = 1; + overlay.VBlankActiveFunc = vblank_active_CRT2; + if(!pPriv->hasTwoOverlays) { + pPriv->displayMode = DISPMODE_SINGLE2; + } + } +#endif } - else { - index = 0; - overlay.VBlankActiveFunc = vblank_active_CRT1; - overlay.GetScanLineFunc = get_scanline_CRT1; + + /* TW: set display mode SR06,32 (CRT1, CRT2 or mirror) */ + set_disptype_regs(pScrn, pPriv); + + /* set (not only calc) merge line buffer */ +#ifdef SISMERGED + if(!pSiS->MergedFB) { +#endif + merge_line_buf(pSiS, pPriv, (overlay.srcW > pPriv->linebufMergeLimit), overlay.srcW, + pPriv->linebufMergeLimit); +#ifdef SISMERGED + } else { + Bool temp1 = FALSE, temp2 = FALSE; + if(overlay.DoFirst) { + if(overlay.srcW > pPriv->linebufMergeLimit) temp1 = TRUE; + } + if(overlay.DoSecond) { + if(overlay.srcW2 > pPriv->linebufMergeLimit) temp2 = TRUE; + } + merge_line_buf_mfb(pSiS, pPriv, temp1, temp2, overlay.srcW, overlay.srcW2, pPriv->linebufMergeLimit); } +#endif + + /* calculate (not set!) line buffer length */ +#ifdef SISMERGED + if((!pSiS->MergedFB) || (overlay.DoFirst)) +#endif + set_line_buf_size_1(&overlay); +#ifdef SISMERGED + if((pSiS->MergedFB) && (overlay.DoSecond)) + set_line_buf_size_2(&overlay); +#endif + /* TW: Do the following in a loop for CRT1 and CRT2 ----------------- */ MIRROR: - setvideoregmask (pSIS, Index_VI_Control_Misc2, index, 0x01); - - /* set scale temporarily */ - { - int dstW = overlay.dstBox.x2 - overlay.dstBox.x1; - int srcW = overlay.srcW; - unsigned char i = 0; - - dstW <<= 1; - while(srcW > dstW) { - dstW <<= 1; - i++; - } - setvideoregmask (pSIS, Index_VI_Scale_Control, i, 0x07); - } - + /* calculate (not set!) scale factor */ +#ifdef SISMERGED + if(pSiS->MergedFB && iscrt2) + calc_scale_factor_2(&overlay, pScrn, pPriv, index, iscrt2); + else +#endif + calc_scale_factor(&overlay, pScrn, pPriv, index, iscrt2); + + /* Select video1 (used for CRT1/or CRT2) or video2 (used for CRT2) */ + setvideoregmask(pSiS, Index_VI_Control_Misc2, index, 0x01); + /* set format */ - set_format(pSIS, &overlay); - + set_format(pSiS, &overlay); + /* set color key */ - /* TODO: update only when colorkey changed */ - /* FIXME, is the RGB order correct? */ - set_colorkey(pSIS, pPriv->colorKey); + set_colorkey(pSiS, pPriv->colorKey); - /* set brightness */ - set_brightness(pSIS, pPriv->brightness); - - /* set overlay */ - set_overlay(pSIS, &overlay); + if(pPriv->usechromakey) { + /* Select chroma key format (300 series only) */ + if(pSiS->VGAEngine == SIS_300_VGA) { + setvideoregmask(pSiS, Index_VI_Control_Misc0, + (pPriv->yuvchromakey ? 0x40 : 0x00), 0x40); + } + set_chromakey(pSiS, pPriv->chromamin, pPriv->chromamax); + } + + /* set brightness, contrast, hue, saturation */ + set_brightness(pSiS, pPriv->brightness); + set_contrast(pSiS, pPriv->contrast); + if(pSiS->VGAEngine == SIS_315_VGA) { + set_hue(pSiS, pPriv->hue); + set_saturation(pSiS, pPriv->saturation); + } + + if(pPriv->dualHeadMode) { +#ifdef SISDUALHEAD + if(!pSiS->SecondHead) { + if(pPriv->updatetvxpos) { + SiS_SetTVxposoffset(pScrn, pPriv->tvxpos); + pPriv->updatetvxpos = FALSE; + } + if(pPriv->updatetvypos) { + SiS_SetTVyposoffset(pScrn, pPriv->tvypos); + pPriv->updatetvypos = FALSE; + } + } +#endif + } else { + if(pPriv->updatetvxpos) { + SiS_SetTVxposoffset(pScrn, pPriv->tvxpos); + pPriv->updatetvxpos = FALSE; + } + if(pPriv->updatetvypos) { + SiS_SetTVyposoffset(pScrn, pPriv->tvypos); + pPriv->updatetvypos = FALSE; + } + } + + /* enable/disable graphics display around overlay + * (Since disabled overlays don't get treated in this + * loop, we omit respective checks here) + */ + + if(!iscrt2) set_disablegfx(pSiS, pPriv->disablegfx, &overlay); + else if(!pPriv->hasTwoOverlays) { + set_disablegfx(pSiS, FALSE, &overlay); + } + set_disablegfxlr(pSiS, pPriv->disablegfxlr, &overlay); + +#ifdef SIS_CP + SIS_CP_VIDEO_SET_CP +#endif + + /* set overlay parameters */ + set_overlay(pSiS, &overlay, pPriv, index, iscrt2); + + if(pSiS->VGAEngine == SIS_315_VGA) { + /* Trigger register copy for 315 series */ + setvideoregmask(pSiS, Index_VI_Control_Misc3, (1 << index), (1 << index)); + } + + /* enable overlay */ + setvideoregmask (pSiS, Index_VI_Control_Misc0, 0x02, 0x02); + + /* loop foot */ + if(pPriv->displayMode & DISPMODE_MIRROR && + index == 0 && + pPriv->hasTwoOverlays) { +#ifdef SISMERGED + if((!pSiS->MergedFB) || overlay.DoSecond) { +#endif + index = 1; iscrt2 = 1; + overlay.VBlankActiveFunc = vblank_active_CRT2; + goto MIRROR; +#ifdef SISMERGED + } +#endif + } - /* enable overlay */ - setvideoregmask (pSIS, Index_VI_Control_Misc0, 0x02, 0x02); - - if((pPriv->displayMode == DISPMODE_MIRROR) && (index == 0)) { - index = 1; - overlay.VBlankActiveFunc = vblank_active_CRT2; - overlay.GetScanLineFunc = get_scanline_CRT2; - goto MIRROR; + pPriv->mustwait = 0; + pPriv->overlayStatus = TRUE; +} + +static FBLinearPtr +SISAllocateOverlayMemory( + ScrnInfoPtr pScrn, + FBLinearPtr linear, + int size +){ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + if(linear) { + if(linear->size >= size) + return linear; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8, + NULL, NULL, NULL); + + if(!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8, + PRIORITY_EXTREME); + + if(max_size < size) return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8, + NULL, NULL, NULL); + } + if (!new_linear) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Xv: Failed to allocate %dK of video memory\n", size/1024); +#ifdef TWDEBUG + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Xv: Allocated %dK of video memory\n", size/1024); +#endif + + return new_linear; } +static void +SISFreeOverlayMemory(ScrnInfoPtr pScrn) +{ + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); -static void -SISStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } +} + +static void +SISStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) { SISPortPrivPtr pPriv = (SISPortPrivPtr)data; - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + + if(pPriv->grabbedByV4L) + return; - REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); - if(exit) { + if(shutdown) { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { - close_overlay(pSIS, pPriv); - } - if(pPriv->fbAreaPtr) { - xf86FreeOffscreenArea(pPriv->fbAreaPtr); - pPriv->fbAreaPtr = NULL; - pPriv->fbSize = 0; + close_overlay(pSiS, pPriv); + pPriv->mustwait = 1; } + SISFreeOverlayMemory(pScrn); pPriv->videoStatus = 0; + pSiS->VideoTimerCallback = NULL; } else { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { - pPriv->videoStatus |= OFF_TIMER; - pPriv->offTime = currentTime.milliseconds + OFF_DELAY; - /* FIXME */ -/* SISDisplayVideo(pScrn, pPriv); */ + pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + pSiS->VideoTimerCallback = SISVideoTimerCallback; } } } - -static int -SISPutImage( - ScrnInfoPtr pScrn, - short src_x, short src_y, +static int +SISPutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, short drw_x, short drw_y, - short src_w, short src_h, + short src_w, short src_h, short drw_w, short drw_h, - int id, unsigned char* buf, - short width, short height, + int id, unsigned char* buf, + short width, short height, Bool sync, RegionPtr clipBoxes, pointer data ){ - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); SISPortPrivPtr pPriv = (SISPortPrivPtr)data; int totalSize=0; - + int depth = pSiS->CurrentLayout.bitsPerPixel >> 3; + int myreds[] = { 0x000000ff, 0x0000f800, 0, 0x00ff0000 }; + + if(pPriv->grabbedByV4L) + return Success; + pPriv->drw_x = drw_x; pPriv->drw_y = drw_y; pPriv->drw_w = drw_w; @@ -1111,160 +3363,712 @@ SISPutImage( pPriv->id = id; pPriv->height = height; + /* TW: Pixel formats: + 1. YU12: 3 planes: H V + Y sample period 1 1 (8 bit per pixel) + V sample period 2 2 (8 bit per pixel, subsampled) + U sample period 2 2 (8 bit per pixel, subsampled) + + Y plane is fully sampled (width*height), U and V planes + are sampled in 2x2 blocks, hence a group of 4 pixels requires + 4 + 1 + 1 = 6 bytes. The data is planar, ie in single planes + for Y, U and V. + 2. UYVY: 3 planes: H V + Y sample period 1 1 (8 bit per pixel) + V sample period 2 1 (8 bit per pixel, subsampled) + U sample period 2 1 (8 bit per pixel, subsampled) + Y plane is fully sampled (width*height), U and V planes + are sampled in 2x1 blocks, hence a group of 4 pixels requires + 4 + 2 + 2 = 8 bytes. The data is bit packed, there are no separate + Y, U or V planes. + Bit order: U0 Y0 V0 Y1 U2 Y2 V2 Y3 ... + 3. I420: Like YU12, but planes U and V are in reverse order. + 4. YUY2: Like UYVY, but order is + Y0 U0 Y1 V0 Y2 U2 Y3 V2 ... + 5. YVYU: Like YUY2, but order is + Y0 V0 Y1 U0 Y2 V2 Y3 U2 ... + */ + switch(id){ case PIXEL_FMT_YV12: + case PIXEL_FMT_I420: + case PIXEL_FMT_NV12: + case PIXEL_FMT_NV21: pPriv->srcPitch = (width + 7) & ~7; - totalSize = (pPriv->srcPitch * height * 3) >> 1; + /* Size = width * height * 3 / 2 */ + totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */ break; case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_YVYU: + case PIXEL_FMT_RGB6: + case PIXEL_FMT_RGB5: default: - pPriv->srcPitch = (width*2 + 3) & ~3; + pPriv->srcPitch = ((width << 1) + 3) & ~3; /* Verified */ + /* Size = width * 2 * height */ totalSize = pPriv->srcPitch * height; } - - /* allocate memory */ - do { - int lines, pitch, depth; - BoxPtr pBox; - - if(totalSize == pPriv->fbSize) - break; - - pPriv->fbSize = totalSize; - /* TODO: use xf86AllocateOffscreenLinear is better */ - if(pPriv->fbAreaPtr) { - /* TODO: resize */ - xf86FreeOffscreenArea(pPriv->fbAreaPtr); - } - depth = (pScrn->bitsPerPixel + 7 ) / 8; - pitch = pScrn->displayWidth * depth; - lines = ((totalSize * 2) / pitch) + 1; - pPriv->fbAreaPtr = xf86AllocateOffscreenArea(pScrn->pScreen, - pScrn->displayWidth, - lines, 0, NULL, NULL, NULL); - - if(!pPriv->fbAreaPtr) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Allocate video memory fails\n"); - return BadAlloc; - } - pBox = &(pPriv->fbAreaPtr->box); - pPriv->bufAddr[0] = (pBox->x1 * depth) + (pBox->y1 * pitch); - pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; - } while(0); + /* make it a multiple of 16 to simplify to copy loop */ + totalSize += 15; + totalSize &= ~15; + + /* allocate memory (we do doublebuffering) */ + if(!(pPriv->linear = SISAllocateOverlayMemory(pScrn, pPriv->linear, + totalSize<<1))) + return BadAlloc; + + /* fixup pointers */ + pPriv->bufAddr[0] = (pPriv->linear->offset * depth); + pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; /* copy data */ - /* TODO: subimage */ - memcpy(pSIS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); - + if((pSiS->XvUseMemcpy) || (totalSize < 16)) { + memcpy(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); + } else { + unsigned long i; + CARD32 *src = (CARD32 *)buf; + CARD32 *dest = (CARD32 *)(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf]); + for(i = 0; i < (totalSize/16); i++) { + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + } + } + SISDisplayVideo(pScrn, pPriv); - /* update cliplist */ - if(!RegionsEqual(&pPriv->clip, clipBoxes)) { - REGION_COPY(pScreen, &pPriv->clip, clipBoxes); - /* draw these */ - XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, - REGION_NUM_RECTS(clipBoxes), - REGION_RECTS(clipBoxes)); - } + /* update cliplist */ + if(pPriv->autopaintColorKey && + (pPriv->grabbedByV4L || +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + (!RegionsEqual(&pPriv->clip, clipBoxes)) || +#else + (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) || +#endif + (pPriv->PrevOverlay != pPriv->NoOverlay))) { + /* We always paint the colorkey for V4L */ + if(!pPriv->grabbedByV4L) +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); +#else + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); +#endif + /* draw these */ + pPriv->PrevOverlay = pPriv->NoOverlay; + if((pPriv->NoOverlay) && (!pSiS->NoAccel)) { + XAAFillMono8x8PatternRects(pScrn, myreds[depth-1], 0x000000, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes), + 0x00422418, 0x18244200, 0, 0); + } else { + if(!pSiS->disablecolorkeycurrent) { +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); +#else + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); +#endif + } + } - if (pPriv->currentBuf == 0) - pPriv->currentBuf = 1; - else - pPriv->currentBuf = 0; - - pPriv->videoStatus = CLIENT_VIDEO_ON; + } - return Success; -} + pPriv->currentBuf ^= 1; + pPriv->videoStatus = CLIENT_VIDEO_ON; -static int + pSiS->VideoTimerCallback = SISVideoTimerCallback; + + return Success; +} + +static int SISQueryImageAttributes( - ScrnInfoPtr pScrn, - int id, - unsigned short *w, unsigned short *h, + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, int *pitches, int *offsets ){ - int pitchY, pitchUV; - int size, sizeY, sizeUV; + int pitchY, pitchUV; + int size, sizeY, sizeUV; if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH; if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT; - if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; - if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; + if(*w > DummyEncoding.width) *w = DummyEncoding.width; + if(*h > DummyEncoding.height) *h = DummyEncoding.height; switch(id) { case PIXEL_FMT_YV12: + case PIXEL_FMT_I420: *w = (*w + 7) & ~7; *h = (*h + 1) & ~1; pitchY = *w; - pitchUV = *w >> 1; - if(pitches) { - pitches[0] = pitchY; - pitches[1] = pitches[2] = pitchUV; + pitchUV = *w >> 1; + if(pitches) { + pitches[0] = pitchY; + pitches[1] = pitches[2] = pitchUV; } - sizeY = pitchY * (*h); - sizeUV = pitchUV * ((*h) >> 1); - if(offsets) { + sizeY = pitchY * (*h); + sizeUV = pitchUV * ((*h) >> 1); + if(offsets) { offsets[0] = 0; offsets[1] = sizeY; offsets[2] = sizeY + sizeUV; } size = sizeY + (sizeUV << 1); - break; + break; + case PIXEL_FMT_NV12: + case PIXEL_FMT_NV21: + *w = (*w + 7) & ~7; + *h = (*h + 1) & ~1; + pitchY = *w; + pitchUV = *w; + if(pitches) { + pitches[0] = pitchY; + pitches[1] = pitchUV; + } + sizeY = pitchY * (*h); + sizeUV = pitchUV * ((*h) >> 1); + if(offsets) { + offsets[0] = 0; + offsets[1] = sizeY; + } + size = sizeY + (sizeUV << 1); + break; case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_YVYU: + case PIXEL_FMT_RGB6: + case PIXEL_FMT_RGB5: default: *w = (*w + 1) & ~1; pitchY = *w << 1; - if(pitches) pitches[0] = pitchY; - if(offsets) offsets[0] = 0; - size = pitchY * (*h); - break; + if(pitches) pitches[0] = pitchY; + if(offsets) offsets[0] = 0; + size = pitchY * (*h); + break; } return size; } static void -SISBlockHandler ( - int i, - pointer blockData, - pointer pTimeout, - pointer pReadmask -){ - ScreenPtr pScreen = screenInfo.screens[i]; - ScrnInfoPtr pScrn = xf86Screens[i]; - SISPtr pSIS = SISPTR(pScrn); +SISVideoTimerCallback(ScrnInfoPtr pScrn, Time now) +{ + SISPtr pSiS = SISPTR(pScrn); + SISPortPrivPtr pPriv = NULL; + unsigned char sridx, cridx; + + pSiS->VideoTimerCallback = NULL; + + if(!pScrn->vtSema) return; + + if(pSiS->adaptor) { + pPriv = GET_PORT_PRIVATE(pScrn); + if(!pPriv->videoStatus) + pPriv = NULL; + } + + if(pPriv) { + if(pPriv->videoStatus & TIMER_MASK) { + UpdateCurrentTime(); + if(pPriv->offTime < currentTime.milliseconds) { + if(pPriv->videoStatus & OFF_TIMER) { + /* Turn off the overlay */ + sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); + close_overlay(pSiS, pPriv); + outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); + pPriv->mustwait = 1; + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + pSiS->VideoTimerCallback = SISVideoTimerCallback; + } else if(pPriv->videoStatus & FREE_TIMER) { + SISFreeOverlayMemory(pScrn); + pPriv->mustwait = 1; + pPriv->videoStatus = 0; + } + } else + pSiS->VideoTimerCallback = SISVideoTimerCallback; + } + } +} + +/* TW: Offscreen surface stuff */ + +static int +SISAllocSurface ( + ScrnInfoPtr pScrn, + int id, + unsigned short w, + unsigned short h, + XF86SurfacePtr surface +) +{ + SISPtr pSiS = SISPTR(pScrn); SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + int size, depth; - pScreen->BlockHandler = pSIS->BlockHandler; - - (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: SISAllocSurface called\n"); +#endif + + if((w < IMAGE_MIN_WIDTH) || (h < IMAGE_MIN_HEIGHT)) + return BadValue; + if((w > DummyEncoding.width) || (h > DummyEncoding.height)) + return BadValue; + + if(pPriv->grabbedByV4L) + return BadAlloc; + + depth = pSiS->CurrentLayout.bitsPerPixel >> 3; + w = (w + 1) & ~1; + pPriv->pitch = ((w << 1) + 63) & ~63; /* Only packed pixel modes supported */ + size = h * pPriv->pitch; /* / depth; - Why? */ + pPriv->linear = SISAllocateOverlayMemory(pScrn, pPriv->linear, size); + if(!pPriv->linear) + return BadAlloc; + + pPriv->offset = pPriv->linear->offset * depth; + + surface->width = w; + surface->height = h; + surface->pScrn = pScrn; + surface->id = id; + surface->pitches = &pPriv->pitch; + surface->offsets = &pPriv->offset; + surface->devPrivate.ptr = (pointer)pPriv; + + close_overlay(pSiS, pPriv); + pPriv->videoStatus = 0; + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + pSiS->VideoTimerCallback = NULL; + pPriv->grabbedByV4L = TRUE; + return Success; +} + +static int +SISStopSurface (XF86SurfacePtr surface) +{ + SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); + SISPtr pSiS = SISPTR(surface->pScrn); + + if(pPriv->grabbedByV4L && pPriv->videoStatus) { + close_overlay(pSiS, pPriv); + pPriv->mustwait = 1; + pPriv->videoStatus = 0; + } + return Success; +} + +static int +SISFreeSurface (XF86SurfacePtr surface) +{ + SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); + + if(pPriv->grabbedByV4L) { + SISStopSurface(surface); + SISFreeOverlayMemory(surface->pScrn); + pPriv->grabbedByV4L = FALSE; + } + return Success; +} + +static int +SISGetSurfaceAttribute ( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value +) +{ + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + + return SISGetPortAttribute(pScrn, attribute, value, (pointer)pPriv); +} + +static int +SISSetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value +) +{ + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);; + + return SISSetPortAttribute(pScrn, attribute, value, (pointer)pPriv); +} + +static int +SISDisplaySurface ( + XF86SurfacePtr surface, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + RegionPtr clipBoxes +) +{ + ScrnInfoPtr pScrn = surface->pScrn; + SISPtr pSiS = SISPTR(pScrn); + SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); + int myreds[] = { 0x000000ff, 0x0000f800, 0, 0x00ff0000 }; + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: DisplaySurface called\n"); +#endif + + if(!pPriv->grabbedByV4L) + return Success; + + pPriv->drw_x = drw_x; + pPriv->drw_y = drw_y; + pPriv->drw_w = drw_w; + pPriv->drw_h = drw_h; + pPriv->src_x = src_x; + pPriv->src_y = src_y; + pPriv->src_w = src_w; + pPriv->src_h = src_h; + pPriv->id = surface->id; + pPriv->height = surface->height; + pPriv->bufAddr[0] = surface->offsets[0]; + pPriv->currentBuf = 0; + pPriv->srcPitch = surface->pitches[0]; - pScreen->BlockHandler = SISBlockHandler; + SISDisplayVideo(pScrn, pPriv); - if(pPriv->videoStatus & TIMER_MASK) { - UpdateCurrentTime(); - if(pPriv->videoStatus & OFF_TIMER) { - if(pPriv->offTime < currentTime.milliseconds) { - /* Turn off the overlay */ - close_overlay(pSIS, pPriv); + if(pPriv->autopaintColorKey) { + if((pPriv->NoOverlay) && (!(pSiS->NoAccel))) { + XAAFillMono8x8PatternRects(pScrn, + myreds[(pSiS->CurrentLayout.bitsPerPixel >> 3) - 1], + 0x000000, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes), + 0x00422418, 0x18244200, 0, 0); - pPriv->videoStatus = FREE_TIMER; - pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - } else { /* FREE_TIMER */ - if(pPriv->freeTime < currentTime.milliseconds) { - if(pPriv->fbAreaPtr) { - xf86FreeOffscreenArea(pPriv->fbAreaPtr); - pPriv->fbAreaPtr = NULL; - pPriv->fbSize = 0; - } - pPriv->videoStatus = 0; - } - } + } else { +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); +#else + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); +#endif + } + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + + return Success; +} + +#define NUMOFFSCRIMAGES_300 4 +#define NUMOFFSCRIMAGES_315 5 + +static XF86OffscreenImageRec SISOffscreenImages[NUMOFFSCRIMAGES_315] = +{ + { + &SISImages[0], /* YUV2 */ + VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, + SISAllocSurface, + SISFreeSurface, + SISDisplaySurface, + SISStopSurface, + SISGetSurfaceAttribute, + SISSetSurfaceAttribute, + 0, 0, /* Rest will be filled in */ + 0, + NULL + }, + { + &SISImages[2], /* UYVY */ + VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, + SISAllocSurface, + SISFreeSurface, + SISDisplaySurface, + SISStopSurface, + SISGetSurfaceAttribute, + SISSetSurfaceAttribute, + 0, 0, /* Rest will be filled in */ + 0, + NULL + } + , + { + &SISImages[4], /* RV15 */ + VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, + SISAllocSurface, + SISFreeSurface, + SISDisplaySurface, + SISStopSurface, + SISGetSurfaceAttribute, + SISSetSurfaceAttribute, + 0, 0, /* Rest will be filled in */ + 0, + NULL + }, + { + &SISImages[5], /* RV16 */ + VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, + SISAllocSurface, + SISFreeSurface, + SISDisplaySurface, + SISStopSurface, + SISGetSurfaceAttribute, + SISSetSurfaceAttribute, + 0, 0, /* Rest will be filled in */ + 0, + NULL + }, + { + &SISImages[6], /* YVYU */ + VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, + SISAllocSurface, + SISFreeSurface, + SISDisplaySurface, + SISStopSurface, + SISGetSurfaceAttribute, + SISSetSurfaceAttribute, + 0, 0, /* Rest will be filled in */ + 0, + NULL + } +}; + +static void +SISInitOffscreenImages(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + int i, num; + + if(pSiS->VGAEngine == SIS_300_VGA) num = NUMOFFSCRIMAGES_300; + else num = NUMOFFSCRIMAGES_315; + + for(i = 0; i <= num; i++) { + SISOffscreenImages[i].max_width = DummyEncoding.width; + SISOffscreenImages[i].max_height = DummyEncoding.height; + if(pSiS->VGAEngine == SIS_300_VGA) { + SISOffscreenImages[i].num_attributes = NUM_ATTRIBUTES_300; + SISOffscreenImages[i].attributes = &SISAttributes_300[0]; + } else { + if(pPriv->hasTwoOverlays) { + SISOffscreenImages[i].num_attributes = NUM_ATTRIBUTES_315; + } else { + SISOffscreenImages[i].num_attributes = NUM_ATTRIBUTES_315 - 1; + } + SISOffscreenImages[i].attributes = &SISAttributes_315[0]; + } + } + xf86XVRegisterOffscreenImages(pScreen, SISOffscreenImages, num); +} + +#ifdef NOT_YET_IMPLEMENTED /* ----------- TW: FOR FUTURE USE -------------------- */ + +/* Set alpha - does not work */ +static void +set_alpha(SISPtr pSiS, CARD8 alpha) +{ + setvideoregmask(pSiS, Index_VI_Key_Overlay_OP, ((alpha & 0x0f) << 4), 0xf0); +} + +/* TW: Set SubPicture Start Address (yet unused) */ +static void +set_subpict_start_offset(SISPtr pSiS, SISOverlayPtr pOverlay, int index) +{ + CARD32 temp; + CARD8 data; + + temp = pOverlay->SubPictAddr >> 4; /* TW: 630 <-> 315 shiftValue? */ + + setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_Low, temp & 0xFF); + setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_Middle, (temp>>8) & 0xFF); + setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_High, (temp>>16) & 0x3F); + if (pSiS->VGAEngine == SIS_315_VGA) { + setvideoreg(pSiS,Index_VI_SubPict_Start_Over, (temp>>22) & 0x01); + /* Submit SubPict offset ? */ + /* data=getvideoreg(pSiS,Index_VI_Control_Misc3); */ + setvideoreg(pSiS,Index_VI_Control_Misc3, (1 << index) | 0x04); } } + +/* TW: Set SubPicture Pitch (yet unused) */ +static void +set_subpict_pitch(SISPtr pSiS, SISOverlayPtr pOverlay, int index) +{ + CARD32 temp; + CARD8 data; + + temp = pOverlay->SubPictPitch >> 4; /* TW: 630 <-> 315 shiftValue? */ + + setvideoreg(pSiS,Index_VI_SubPict_Buf_Pitch, temp & 0xFF); + if (pSiS->VGAEngine == SIS_315_VGA) { + setvideoreg(pSiS,Index_VI_SubPict_Buf_Pitch_High, (temp>>8) & 0xFF); + /* Submit SubPict pitch ? */ + /* data=getvideoreg(pSiS,Index_VI_Control_Misc3); */ + setvideoreg(pSiS,Index_VI_Control_Misc3, (1 << index) | 0x04); + } +} + +/* TW: Calculate and set SubPicture scaling (untested, unused yet) */ +static void +set_subpict_scale_factor(SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, + SISPortPrivPtr pPriv, int index, int iscrt2) +{ + SISPtr pSiS = SISPTR(pScrn); + CARD32 I=0,mult=0; + int flag=0; + + int dstW = pOverlay->SubPictdstBox.x2 - pOverlay->SubPictdstBox.x1; + int dstH = pOverlay->SubPictdstBox.y2 - pOverlay->SubPictdstBox.y1; + int srcW = pOverlay->SubPictsrcW; + int srcH = pOverlay->SubPictsrcH; + CARD16 LCDheight = pSiS->LCDheight; + int srcPitch = pOverlay->SubPictOrigPitch; + int origdstH = dstH; + + /* TW: Stretch image due to idiotic LCD "auto"-scaling */ + /* INCOMPLETE and INCORRECT - See set_scale_factor() */ + if ( (pPriv->bridgeIsSlave) && (pSiS->VBFlags & CRT2_LCD) ) { + dstH = (dstH * LCDheight) / pOverlay->SCREENheight; + } else if ((index) && (pSiS->VBFlags & CRT2_LCD)) { + dstH = (dstH * LCDheight) / pOverlay->SCREENheight; + if (pPriv->displayMode == DISPMODE_MIRROR) flag = 1; + } + + if (dstW == srcW) { + pOverlay->SubPictHUSF = 0x00; + pOverlay->SubPictIntBit = 0x01; + } else if (dstW > srcW) { + pOverlay->SubPictHUSF = (srcW << 16) / dstW; + pOverlay->SubPictIntBit = 0x00; + } else { + int tmpW = dstW; + + I = 0x00; + while (srcW >= tmpW) { + tmpW <<= 1; + I++; + } + pOverlay->SubPictwHPre = (CARD8)(I - 1); + dstW <<= (I - 1); + if ((srcW % dstW)) + pOverlay->SubPictHUSF = ((srcW - dstW) << 16) / dstW; + else + pOverlay->SubPictHUSF = 0x00; + + pOverlay->SubPictIntBit = 0x01; + } + + if (dstH == srcH) { + pOverlay->SubPictVUSF = 0x00; + pOverlay->SubPictIntBit |= 0x02; + } else if (dstH > srcH) { + dstH += 0x02; + pOverlay->SubPictVUSF = (srcH << 16) / dstH; + /* pOverlay->SubPictIntBit |= 0x00; */ + } else { + CARD32 realI; + + I = realI = srcH / dstH; + pOverlay->SubPictIntBit |= 0x02; + + if (I < 2) { + pOverlay->SubPictVUSF = ((srcH - dstH) << 16) / dstH; + /* TW: Needed for LCD-scaling modes */ + if ((flag) && (mult = (srcH / origdstH)) >= 2) + pOverlay->SubPictPitch /= mult; + } else { + if (((srcPitch * I)>>2) > 0xFFF) { + I = (0xFFF*2/srcPitch); + pOverlay->SubPictVUSF = 0xFFFF; + } else { + dstH = I * dstH; + if (srcH % dstH) + pOverlay->SubPictVUSF = ((srcH - dstH) << 16) / dstH; + else + pOverlay->SubPictVUSF = 0x00; + } + /* set video frame buffer offset */ + pOverlay->SubPictPitch = (CARD16)(srcPitch*I); + } + } + /* set SubPicture scale factor */ + setvideoreg (pSiS, Index_VI_SubPict_Hor_Scale_Low, (CARD8)(pOverlay->SubPictHUSF)); + setvideoreg (pSiS, Index_VI_SubPict_Hor_Scale_High, (CARD8)((pOverlay->SubPictHUSF)>>8)); + setvideoreg (pSiS, Index_VI_SubPict_Vert_Scale_Low, (CARD8)(pOverlay->SubPictVUSF)); + setvideoreg (pSiS, Index_VI_SubPict_Vert_Scale_High,(CARD8)((pOverlay->SubPictVUSF)>>8)); + + setvideoregmask (pSiS, Index_VI_SubPict_Scale_Control, + (pOverlay->SubPictIntBit << 3) | + (pOverlay->SubPictwHPre), 0x7f); +} + +/* TW: Set SubPicture Preset (yet unused) */ +static void +set_subpict_preset(SISPtr pSiS, SISOverlayPtr pOverlay) +{ + CARD32 temp; + CARD8 data; + + temp = pOverlay->SubPictPreset >> 4; /* TW: 630 <-> 315 ? */ + + setvideoreg(pSiS,Index_VI_SubPict_Buf_Preset_Low, temp & 0xFF); + setvideoreg(pSiS,Index_VI_SubPict_Buf_Preset_Middle, (temp>>8) & 0xFF); + data = getvideoreg(pSiS,Index_VI_SubPict_Buf_Start_High); + if (temp > 0xFFFF) + data |= 0x40; + else + data &= ~0x40; + setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_High, data); +} + +static void +enable_subpict_overlay(SISPtr pSiS, Bool enable) +{ + setvideoregmask(pSiS, Index_VI_SubPict_Scale_Control, + enable ? 0x40 : 0x00, + 0x40); +} + +/* TW: Set overlay for subpicture */ +static void +set_subpict_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index) +{ + ScrnInfoPtr pScrn = pSiS->pScrn; + + set_subpict_pitch(pSiS, &overlay, index); + set_subpict_start_offset(pSiS, &overlay, index); + set_subpict_scale_factor(&overlay, pScrn, pPriv, index); + /* set_subpict_preset(pSiS, &overlay); */ + /* enable_subpict_overlay(pSiS, 1); */ +} + + +/* TW: Set MPEG Field Preset (yet unused) */ +static void +set_mpegfield_preset(SISPtr pSiS, SISOverlayPtr pOverlay) +{ + setvideoreg(pSiS,Index_MPEG_Y_Buf_Preset_Low, pOverlay->MPEG_Y & 0xFF); + setvideoreg(pSiS,Index_MPEG_Y_Buf_Preset_Middle, (pOverlay->MPEG_Y>>8) & 0xFF); + + setvideoreg(pSiS,Index_MPEG_UV_Buf_Preset_Low, pOverlay->MPEG_UV & 0xFF); + setvideoreg(pSiS,Index_MPEG_UV_Buf_Preset_Middle, (pOverlay->MPEG_UV>>8) & 0xFF); + + setvideoreg(pSiS,Index_MPEG_Y_UV_Buf_Preset_High, + ((pOverlay->MPEG_Y>>16) & 0x0F) | ((pOverlay->MPEG_UV>>12) & 0xF0)); +} + +static void +set_mpegfield_scale(SISPtr pSiS, SISOverlayPtr pOverlay) +{ + /* Empty for now */ +} + +#endif /* ------------------------------------------------------------------- */ + + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h index d377deeda..1a1cc4297 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h @@ -1,5 +1,36 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.3 2003/02/10 01:14:16 tsi Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.8 2003/06/26 22:35:19 twini Exp $ */ +/* + * General type definitions for universal mode switching modules + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Thomas Winischhofer <thomas@winischhofer.net> + * Silicon Integrated Systems + * + */ #ifndef _VGATYPES_ #define _VGATYPES_ @@ -7,7 +38,7 @@ #include "xf86Pci.h" #endif -#ifdef LINUX_KERNEL /* TW: We don't want the X driver to depend on kernel source */ +#ifdef LINUX_KERNEL /* We don't want the X driver to depend on kernel source */ #include <linux/ioctl.h> #endif @@ -74,18 +105,15 @@ typedef void VOID; typedef UCHAR BOOLEAN; #endif -#ifndef WINCE_HEADER #ifndef bool typedef UCHAR bool; #endif -#endif /*WINCE_HEADER*/ #ifndef VBIOS_VER_MAX_LENGTH #define VBIOS_VER_MAX_LENGTH 4 #endif #ifndef LINUX_KERNEL /* For kernel, this is defined in sisfb.h */ -#ifndef WIN2000 #ifndef SIS_CHIP_TYPE typedef enum _SIS_CHIP_TYPE { SIS_VGALegacy = 0, @@ -103,33 +131,28 @@ typedef enum _SIS_CHIP_TYPE { SIS_550, SIS_650, SIS_740, - SIS_330, + SIS_330, + SIS_660, + SIS_760, MAX_SIS_CHIP } SIS_CHIP_TYPE; #endif #endif -#endif -#ifndef WIN2000 #ifndef SIS_VB_CHIP_TYPE typedef enum _SIS_VB_CHIP_TYPE { VB_CHIP_Legacy = 0, VB_CHIP_301, - VB_CHIP_301B, + VB_CHIP_301B, VB_CHIP_301LV, - VB_CHIP_301LVX, VB_CHIP_302, VB_CHIP_302B, VB_CHIP_302LV, - VB_CHIP_302LVX, - VB_CHIP_303, VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */ MAX_VB_CHIP } SIS_VB_CHIP_TYPE; #endif -#endif -#ifndef WIN2000 #ifndef SIS_LCD_TYPE typedef enum _SIS_LCD_TYPE { LCD_INVALID = 0, @@ -141,18 +164,20 @@ typedef enum _SIS_LCD_TYPE { LCD_1600x1200, LCD_1920x1440, LCD_2048x1536, - LCD_320x480, /* TW: FSTN */ + LCD_320x480, /* FSTN, DSTN */ LCD_1400x1050, LCD_1152x864, LCD_1152x768, LCD_1280x768, LCD_1024x600, + LCD_640x480_2, /* FSTN, DSTN */ + LCD_640x480_3, /* FSTN, DSTN */ + LCD_848x480, + LCD_CUSTOM, LCD_UNKNOWN } SIS_LCD_TYPE; #endif -#endif -#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/ #ifndef PSIS_DSReg typedef struct _SIS_DSReg { @@ -167,7 +192,6 @@ typedef struct _SIS_HW_DEVICE_INFO SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO; typedef BOOLEAN (*PSIS_QUERYSPACE) (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *); - struct _SIS_HW_DEVICE_INFO { PVOID pDevice; /* The pointer to the physical device data structure @@ -178,7 +202,7 @@ struct _SIS_HW_DEVICE_INFO /* Note:ROM image file is the file of VBIOS ROM */ BOOLEAN UseROM; /* TW: Use the ROM image if provided */ - + UCHAR *pjCustomizedROMImage;/* base virtual address of ROM image file. */ /* wincE:ROM image file is the file for OEM */ /* customized table */ @@ -200,7 +224,7 @@ struct _SIS_HW_DEVICE_INFO /* defined in the data structure type */ /* "SIS_VB_CHIP_TYPE" */ - USHORT usExternalChip; /* NO VB or other video bridge(not */ + USHORT usExternalChip; /* NO VB or other video bridge (other than */ /* SiS video bridge) */ /* if ujVBChipID = VB_CHIP_UNKNOWN, */ /* then bit0=1 : LVDS,bit1=1 : trumpion, */ @@ -212,7 +236,7 @@ struct _SIS_HW_DEVICE_INFO /* 011:Trumpion LVDS Scaling Chip */ /* 100:LVDS(LCD-out)+Chrontel 7005 */ /* 101:Single Chrontel 7005 */ - /* TW: This has changed on 310/325 series! */ + /* TW: This has changed on 315 series! */ ULONG ulCRT2LCDType; /* defined in the data structure type */ /* "SIS_LCD_TYPE" */ @@ -239,13 +263,16 @@ struct _SIS_HW_DEVICE_INFO UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH]; UCHAR pdc; /* TW: PanelDelayCompensation */ + +#ifdef LINUX_KERNEL + BOOLEAN Is301BDH; +#endif #ifdef LINUX_XF86 PCITAG PciTag; /* PCI Tag for Linux XF86 */ #endif }; #endif -#endif /* TW: Addtional IOCTL for communication sisfb <> X driver */ @@ -282,13 +309,19 @@ struct _SISFB_INFO { unsigned int sisfb_pcifunc; unsigned char sisfb_lcdpdc; + + unsigned char sisfb_lcda; + + unsigned long sisfb_vbflags; + unsigned long sisfb_currentvbflags; + + int sisfb_scalelcd; + unsigned long sisfb_specialtiming; - char reserved[236]; /* for future use */ + char reserved[219]; /* for future use */ }; #endif -#ifndef WIN2000 -#ifndef WINCE_HEADER #ifndef BUS_DATA_TYPE typedef enum _BUS_DATA_TYPE { ConfigurationSpaceUndefined = -1, @@ -306,7 +339,6 @@ typedef enum _BUS_DATA_TYPE { MaximumBusDataType } BUS_DATA_TYPE, *PBUS_DATA_TYPE; #endif -#endif /* WINCE_HEADER */ #ifndef PCI_TYPE0_ADDRESSES #define PCI_TYPE0_ADDRESSES 6 @@ -316,7 +348,6 @@ typedef enum _BUS_DATA_TYPE { #define PCI_TYPE1_ADDRESSES 2 #endif -#ifndef WINCE_HEADER #ifndef PCI_COMMON_CONFIG typedef struct _PCI_COMMON_CONFIG { USHORT VendorID; /* (ro) */ @@ -354,7 +385,6 @@ typedef struct _PCI_COMMON_CONFIG { } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; #endif -#endif /* WINCE_HEADER */ #ifndef FIELD_OFFSET #define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field)) @@ -363,6 +393,6 @@ typedef struct _PCI_COMMON_CONFIG { #ifndef PCI_COMMON_HDR_LENGTH #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific)) #endif -#endif #endif + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h index 700598676..4e6156207 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h @@ -1,5 +1,37 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.3 2003/02/10 01:14:17 tsi Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.11 2003/08/07 12:52:24 twini Exp $ */ +/* + * General structure definitions for universal mode switching modules + * + * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria + * + * If distributed as part of the linux kernel, the contents of this file + * is entirely covered by the GPL. + * + * Otherwise, the following terms apply: + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Thomas Winischhofer <thomas@winischhofer.net> + * Silicon Integrated Systems + * + */ + #ifdef _INIT_ #define EXTERN #else @@ -60,7 +92,6 @@ typedef struct _SiS_LVDSCRT1DataStruct UCHAR CR[15]; } SiS_LVDSCRT1DataStruct; -/*add for LCDA*/ typedef struct _SiS_LCDACRT1DataStruct { UCHAR CR[17]; @@ -113,9 +144,7 @@ typedef struct _SiS_ExtStruct UCHAR Ext_ModeID; USHORT Ext_ModeFlag; USHORT Ext_ModeInfo; - USHORT Ext_Point; USHORT Ext_VESAID; - UCHAR Ext_VESAMEMSize; UCHAR Ext_RESINFO; UCHAR VB_ExtTVFlickerIndex; UCHAR VB_ExtTVEdgeIndex; @@ -132,7 +161,6 @@ typedef struct _SiS_Ext2Struct UCHAR ModeID; USHORT XRes; USHORT YRes; - USHORT ROM_OFFSET; } SiS_Ext2Struct; typedef struct _SiS_Part2PortTblStruct @@ -185,6 +213,16 @@ typedef struct _SiS_ModeResInfoStruct typedef UCHAR DRAM4Type[4]; +/* Defines for SiS_Customt */ +#define CUT_NONE 0 +#define CUT_FORCENONE 1 +#define CUT_BARCO1366 2 +#define CUT_BARCO1024 3 +#define CUT_COMPAQ1280 4 +#define CUT_COMPAQ12802 5 +#define CUT_PANEL848 6 +#define CUT_CLEVO1024 7 + typedef struct _SiS_Private { #ifdef LINUX_KERNEL @@ -200,24 +238,34 @@ typedef struct _SiS_Private USHORT SiS_P3c7; USHORT SiS_P3c8; USHORT SiS_P3c9; + USHORT SiS_P3cb; + USHORT SiS_P3cd; USHORT SiS_P3da; USHORT SiS_Part1Port; USHORT SiS_Part2Port; USHORT SiS_Part3Port; USHORT SiS_Part4Port; USHORT SiS_Part5Port; + USHORT SiS_VidCapt; + USHORT SiS_VidPlay; USHORT SiS_IF_DEF_LVDS; USHORT SiS_IF_DEF_TRUMPION; USHORT SiS_IF_DEF_DSTN; USHORT SiS_IF_DEF_FSTN; USHORT SiS_IF_DEF_CH70xx; USHORT SiS_IF_DEF_HiVision; + USHORT SiS_SysFlags; UCHAR SiS_VGAINFO; +#ifndef LINUX_KERNEL + USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4; +#endif BOOLEAN SiS_UseROM; int SiS_CHOverScan; BOOLEAN SiS_CHSOverScan; BOOLEAN SiS_ChSW; + BOOLEAN SiS_UseLCDA; int SiS_UseOEM; + ULONG SiS_CustomT; USHORT SiS_Backup70xx; USHORT SiS_CRT1Mode; USHORT SiS_flag_clearbuffer; @@ -271,15 +319,18 @@ typedef struct _SiS_Private USHORT SiS_Panel1280x768; USHORT SiS_Panel1024x600; USHORT SiS_Panel640x480; + USHORT SiS_Panel640x480_2; + USHORT SiS_Panel640x480_3; USHORT SiS_Panel1152x864; + USHORT SiS_PanelCustom; + USHORT SiS_PanelBarco1366; USHORT SiS_PanelMax; USHORT SiS_PanelMinLVDS; USHORT SiS_PanelMin301; USHORT SiS_ChrontelInit; - /* Pointers: */ const SiS_StStruct *SiS_SModeIDTable; - const SiS_StandTableStruct *SiS_StandTable; + SiS_StandTableStruct *SiS_StandTable; const SiS_ExtStruct *SiS_EModeIDTable; const SiS_Ext2Struct *SiS_RefIndex; const SiS_VBModeStruct *SiS_VBModeIDTable; @@ -317,7 +368,7 @@ typedef struct _SiS_Private const USHORT *pSiS_RGBSenseData; const USHORT *pSiS_VideoSenseData; const USHORT *pSiS_YCSenseData; - const USHORT *pSiS_RGBSenseData2; /*301b*/ + const USHORT *pSiS_RGBSenseData2; const USHORT *pSiS_VideoSenseData2; const USHORT *pSiS_YCSenseData2; #endif @@ -341,22 +392,22 @@ typedef struct _SiS_Private const SiS_LCDDataStruct *SiS_LCD1280x960Data; const SiS_LCDDataStruct *SiS_NoScaleData1400x1050; const SiS_LCDDataStruct *SiS_NoScaleData1600x1200; + const SiS_LCDDataStruct *SiS_NoScaleData1280x768; const SiS_LCDDataStruct *SiS_StLCD1400x1050Data; const SiS_LCDDataStruct *SiS_StLCD1600x1200Data; + const SiS_LCDDataStruct *SiS_StLCD1280x768Data; const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data; const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data; + const SiS_LCDDataStruct *SiS_ExtLCD1280x768Data; + const SiS_LCDDataStruct *SiS_NoScaleData; const SiS_TVDataStruct *SiS_StPALData; const SiS_TVDataStruct *SiS_ExtPALData; const SiS_TVDataStruct *SiS_StNTSCData; const SiS_TVDataStruct *SiS_ExtNTSCData; -#ifdef oldHV - const SiS_TVDataStruct *SiS_St1HiTVData; const SiS_TVDataStruct *SiS_St2HiTVData; const SiS_TVDataStruct *SiS_ExtHiTVData; -#endif const UCHAR *SiS_NTSCTiming; const UCHAR *SiS_PALTiming; -#ifdef oldHV const UCHAR *SiS_HiTVExtTiming; const UCHAR *SiS_HiTVSt1Timing; const UCHAR *SiS_HiTVSt2Timing; @@ -364,7 +415,6 @@ typedef struct _SiS_Private const UCHAR *SiS_HiTVGroup3Data; const UCHAR *SiS_HiTVGroup3Simu; const UCHAR *SiS_HiTVGroup3Text; -#endif const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl; const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS; const SiS_LVDSDataStruct *SiS_LVDS800x600Data_1; @@ -377,6 +427,8 @@ typedef struct _SiS_Private const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_2; const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_1; const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_2; const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_1; const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_2; const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_1; @@ -384,12 +436,19 @@ typedef struct _SiS_Private const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_1; const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_2; const SiS_LVDSDataStruct *SiS_LVDS640x480Data_1; + const SiS_LVDSDataStruct *SiS_LVDS640x480Data_2; const SiS_LVDSDataStruct *SiS_LVDS320x480Data_1; const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_1; const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_2; const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_1; const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_2; const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1; + const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_1; + const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_2; + const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_1; + const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_2; + const SiS_LVDSDataStruct *SiS_LVDS848x480Data_1; + const SiS_LVDSDataStruct *SiS_LVDS848x480Data_2; const SiS_LVDSDataStruct *SiS_CHTVUNTSCData; const SiS_LVDSDataStruct *SiS_CHTVONTSCData; const SiS_LVDSDataStruct *SiS_CHTVUPALData; @@ -415,6 +474,7 @@ typedef struct _SiS_Private const SiS_LVDSDesStruct *SiS_PanelType0d_1; const SiS_LVDSDesStruct *SiS_PanelType0e_1; const SiS_LVDSDesStruct *SiS_PanelType0f_1; + const SiS_LVDSDesStruct *SiS_PanelTypeNS_1; const SiS_LVDSDesStruct *SiS_PanelType00_2; const SiS_LVDSDesStruct *SiS_PanelType01_2; const SiS_LVDSDesStruct *SiS_PanelType02_2; @@ -431,6 +491,7 @@ typedef struct _SiS_Private const SiS_LVDSDesStruct *SiS_PanelType0d_2; const SiS_LVDSDesStruct *SiS_PanelType0e_2; const SiS_LVDSDesStruct *SiS_PanelType0f_2; + const SiS_LVDSDesStruct *SiS_PanelTypeNS_2; const SiS_LVDSDesStruct *LVDS1024x768Des_1; const SiS_LVDSDesStruct *LVDS1280x1024Des_1; @@ -479,6 +540,12 @@ typedef struct _SiS_Private const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2_H; const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1; const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3_H; const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC; const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC; const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL; @@ -508,7 +575,6 @@ typedef struct _SiS_Private const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2_H; const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2_H; - /* TW: New for 650/301LV */ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1; const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1; const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1; @@ -540,6 +606,9 @@ typedef struct _SiS_Private const UCHAR *SiS_CHTVVCLKUPALN; const UCHAR *SiS_CHTVVCLKOPALN; const UCHAR *SiS_CHTVVCLKSOPAL; + + USHORT PanelXRes; + USHORT PanelYRes; BOOLEAN UseCustomMode; BOOLEAN CRT1UsesCustomMode; @@ -561,10 +630,42 @@ typedef struct _SiS_Private UCHAR CSR2B; UCHAR CSR2C; USHORT CSRClock; + USHORT CSRClock_CRT1; USHORT CModeFlag; + USHORT CModeFlag_CRT1; USHORT CInfoFlag; + BOOLEAN SiS_CHPALM; BOOLEAN SiS_CHPALN; + + BOOLEAN Backup; + UCHAR Backup_Mode; + UCHAR Backup_14; + UCHAR Backup_15; + UCHAR Backup_16; + UCHAR Backup_17; + UCHAR Backup_18; + UCHAR Backup_19; + UCHAR Backup_1a; + UCHAR Backup_1b; + UCHAR Backup_1c; + UCHAR Backup_1d; + + int UsePanelScaler; + + USHORT CP_Vendor, CP_Product; + BOOLEAN CP_HaveCustomData; + int CP_PreferredX, CP_PreferredY; + int CP_MaxX, CP_MaxY, CP_MaxClock; + int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */ + int CP_HTotal[7], CP_VTotal[7]; + int CP_HSyncStart[7], CP_VSyncStart[7]; + int CP_HSyncEnd[7], CP_VSyncEnd[7]; + int CP_HBlankStart[7], CP_VBlankStart[7]; + int CP_HBlankEnd[7], CP_VBlankEnd[7]; + int CP_Clock[7]; + BOOLEAN CP_DataValid[7]; + BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7]; } SiS_Private; #endif |