1/*
2 * SiS driver option evaluation
3 *
4 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1) Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2) Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3) The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors:  	Thomas Winischhofer <thomas@winischhofer.net>
29 *              ?
30 */
31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "sis.h"
37
38#include "xf86str.h"
39#include "xf86Cursor.h"
40
41typedef enum {
42    OPTION_SW_CURSOR,
43    OPTION_HW_CURSOR,
44    OPTION_ACCEL,
45    OPTION_ACCELMETHOD,
46    OPTION_TURBOQUEUE,
47    OPTION_FAST_VRAM,
48    OPTION_HOSTBUS,
49    OPTION_RENDER,
50    OPTION_FORCE_CRT1TYPE,
51    OPTION_FORCE_CRT2TYPE,
52    OPTION_YPBPRAR,
53    OPTION_SHADOW_FB,
54    OPTION_DRI,
55    OPTION_AGP_SIZE,
56    OPTION_ROTATE,
57    OPTION_REFLECT,
58    OPTION_XVIDEO,
59    OPTION_VESA,
60    OPTION_MAXXFBMEM,
61    OPTION_FORCECRT1,
62    OPTION_XVONCRT2,
63    OPTION_PDC,
64    OPTION_PDCA,
65    OPTION_EMI,
66    OPTION_TVSTANDARD,
67    OPTION_USEROMDATA,
68    OPTION_INTERNALMODES,
69    OPTION_USEOEM,
70    OPTION_YV12,
71    OPTION_CHTVOVERSCAN,
72    OPTION_CHTVSOVERSCAN,
73    OPTION_CHTVLUMABANDWIDTHCVBS,
74    OPTION_CHTVLUMABANDWIDTHSVIDEO,
75    OPTION_CHTVLUMAFLICKERFILTER,
76    OPTION_CHTVCHROMABANDWIDTH,
77    OPTION_CHTVCHROMAFLICKERFILTER,
78    OPTION_CHTVCVBSCOLOR,
79    OPTION_CHTVTEXTENHANCE,
80    OPTION_CHTVCONTRAST,
81    OPTION_SISTVEDGEENHANCE,
82    OPTION_SISTVANTIFLICKER,
83    OPTION_SISTVSATURATION,
84    OPTION_SISTVCHROMAFILTER,
85    OPTION_SISTVLUMAFILTER,
86    OPTION_SISTVCOLCALIBFINE,
87    OPTION_SISTVCOLCALIBCOARSE,
88    OPTION_TVXPOSOFFSET,
89    OPTION_TVYPOSOFFSET,
90    OPTION_TVXSCALE,
91    OPTION_TVYSCALE,
92    OPTION_SIS6326ANTIFLICKER,
93    OPTION_SIS6326ENABLEYFILTER,
94    OPTION_SIS6326YFILTERSTRONG,
95    OPTION_SIS6326FORCETVPPLUG,
96    OPTION_SIS6326FSCADJUST,
97    OPTION_CHTVTYPE,
98    OPTION_USERGBCURSOR,
99    OPTION_USERGBCURSORBLEND,
100    OPTION_USERGBCURSORBLENDTH,
101    OPTION_RESTOREBYSET,
102    OPTION_DDCFORCRT2,
103    OPTION_FORCECRT2REDETECTION,
104    OPTION_SENSEYPBPR,
105    OPTION_CRT1GAMMA,
106    OPTION_CRT2GAMMA,
107    OPTION_XVGAMMA,
108    OPTION_XVDEFCONTRAST,
109    OPTION_XVDEFBRIGHTNESS,
110    OPTION_XVDEFHUE,
111    OPTION_XVDEFSATURATION,
112    OPTION_XVDEFDISABLEGFX,
113    OPTION_XVDEFDISABLEGFXLR,
114    OPTION_XVMEMCPY,
115    OPTION_XVBENCHCPY,
116#ifndef SISCHECKOSSSE
117    OPTION_XVSSECOPY,
118#endif
119    OPTION_XVUSECHROMAKEY,
120    OPTION_XVCHROMAMIN,
121    OPTION_XVCHROMAMAX,
122    OPTION_XVDISABLECOLORKEY,
123    OPTION_XVINSIDECHROMAKEY,
124    OPTION_XVYUVCHROMAKEY,
125    OPTION_XVDEFAULTADAPTOR,
126    OPTION_SCALELCD,
127    OPTION_CENTERLCD,
128    OPTION_SPECIALTIMING,
129    OPTION_LVDSHL,
130    OPTION_PRGB,
131    OPTION_ENABLEHOTKEY,
132    OPTION_MERGEDFB,
133    OPTION_MERGEDFBAUTO,
134    OPTION_CRT2HSYNC,
135    OPTION_CRT2VREFRESH,
136    OPTION_CRT2POS,
137    OPTION_METAMODES,
138    OPTION_SISXINERAMA,
139    OPTION_CRT2ISSCRN0,
140    OPTION_MERGEDDPI,
141    OPTION_MERGEDFBNONRECT,
142    OPTION_MERGEDFBMOUSER,
143    OPTION_ENABLESISCTRL,
144    OPTION_STOREDBRI,
145    OPTION_STOREDBRI2,
146    OPTION_NEWSTOREDBRI,
147    OPTION_NEWSTOREDBRI2,
148    OPTION_NEWSTOREDCON,
149    OPTION_NEWSTOREDCON2,
150    OPTION_CRT1SATGAIN,
151    OPTION_OVERRULERANGES,
152    OPTION_FORCE1ASPECT,
153    OPTION_FORCE2ASPECT,
154    OPTION_TVBLUE,
155#ifdef SIS_CP
156    SIS_CP_OPT_OPTIONS
157#endif
158    OPTION_PSEUDO
159} SISOpts;
160
161static const OptionInfoRec SISOptions[] = {
162    { OPTION_ACCEL,			"Accel",			OPTV_BOOLEAN,	{0}, FALSE },
163#if defined(SIS_USE_XAA) && defined(SIS_USE_EXA)
164    { OPTION_ACCELMETHOD,		"AccelMethod",			OPTV_STRING,	{0}, FALSE },
165#endif
166    { OPTION_TURBOQUEUE,		"TurboQueue",			OPTV_BOOLEAN,	{0}, FALSE },
167    { OPTION_FAST_VRAM,			"FastVram",			OPTV_BOOLEAN,	{0}, FALSE },
168    { OPTION_HOSTBUS,			"HostBus",			OPTV_BOOLEAN,	{0}, FALSE },
169    { OPTION_RENDER,			"RenderAcceleration",		OPTV_BOOLEAN,	{0}, FALSE },
170    { OPTION_FORCE_CRT1TYPE,		"ForceCRT1Type",		OPTV_STRING,	{0}, FALSE },
171    { OPTION_FORCE_CRT2TYPE,		"ForceCRT2Type",		OPTV_STRING,	{0}, FALSE },
172    { OPTION_SHADOW_FB,			"ShadowFB",			OPTV_BOOLEAN,	{0}, FALSE },
173    { OPTION_DRI,			"DRI",				OPTV_BOOLEAN,	{0}, FALSE },
174    { OPTION_AGP_SIZE,			"AGPSize",			OPTV_INTEGER,	{0}, FALSE },
175    { OPTION_AGP_SIZE,			"GARTSize",			OPTV_INTEGER,	{0}, FALSE },
176    { OPTION_VESA,			"Vesa",				OPTV_BOOLEAN,	{0}, FALSE },
177    { OPTION_MAXXFBMEM,			"MaxXFBMem",			OPTV_INTEGER,	{0}, FALSE },
178    { OPTION_ENABLESISCTRL,		"EnableSiSCtrl",		OPTV_BOOLEAN,	{0}, FALSE },
179    { OPTION_SW_CURSOR,			"SWCursor",			OPTV_BOOLEAN,	{0}, FALSE },
180    { OPTION_HW_CURSOR,			"HWCursor",			OPTV_BOOLEAN,	{0}, FALSE },
181    { OPTION_USERGBCURSOR, 		"UseColorHWCursor",		OPTV_BOOLEAN,	{0}, FALSE },
182    { OPTION_ROTATE,			"Rotate",			OPTV_STRING,	{0}, FALSE },
183    { OPTION_REFLECT,			"Reflect",			OPTV_STRING,	{0}, FALSE },
184    { OPTION_XVIDEO,			"Xvideo",			OPTV_BOOLEAN,	{0}, FALSE },
185    { OPTION_INTERNALMODES,		"InternalModes",		OPTV_BOOLEAN,	{0}, FALSE },
186    { OPTION_OVERRULERANGES,		"OverruleFrequencyRanges",	OPTV_BOOLEAN,	{0}, FALSE },
187    { OPTION_RESTOREBYSET,		"RestoreBySetMode", 		OPTV_BOOLEAN,	{0}, FALSE },
188    { OPTION_FORCECRT1,			"ForceCRT1",			OPTV_BOOLEAN,	{0}, FALSE },
189    { OPTION_XVONCRT2,			"XvOnCRT2",			OPTV_BOOLEAN,	{0}, FALSE },
190    { OPTION_PDC,			"PanelDelayCompensation",	OPTV_INTEGER,	{0}, FALSE },
191    { OPTION_PDC,			"PDC", 				OPTV_INTEGER,	{0}, FALSE },
192    { OPTION_PDC,			"PanelDelayCompensation2",	OPTV_INTEGER,	{0}, FALSE },
193    { OPTION_PDC,			"PDC2", 			OPTV_INTEGER,	{0}, FALSE },
194    { OPTION_PDCA,			"PanelDelayCompensation1",	OPTV_INTEGER,	{0}, FALSE },
195    { OPTION_PDCA,			"PDC1",				OPTV_INTEGER,	{0}, FALSE },
196    { OPTION_EMI,			"EMI", 				OPTV_INTEGER,	{0}, FALSE },
197    { OPTION_LVDSHL,			"LVDSHL", 			OPTV_INTEGER,	{0}, FALSE },
198    { OPTION_PRGB,			"ForcePanelRGB",		OPTV_INTEGER,	{0}, FALSE },
199    { OPTION_SPECIALTIMING,		"SpecialTiming",		OPTV_STRING,	{0}, FALSE },
200    { OPTION_TVSTANDARD,		"TVStandard",			OPTV_STRING,	{0}, FALSE },
201    { OPTION_USEROMDATA,		"UseROMData",			OPTV_BOOLEAN,	{0}, FALSE },
202    { OPTION_USEOEM, 			"UseOEMData",			OPTV_BOOLEAN,	{0}, FALSE },
203    { OPTION_YV12, 			"YV12",				OPTV_BOOLEAN,	{0}, FALSE },
204    { OPTION_CHTVTYPE,			"CHTVType",			OPTV_BOOLEAN,	{0}, FALSE },
205    { OPTION_CHTVOVERSCAN,		"CHTVOverscan",			OPTV_BOOLEAN,	{0}, FALSE },
206    { OPTION_CHTVSOVERSCAN,		"CHTVSuperOverscan",		OPTV_BOOLEAN,	{0}, FALSE },
207    { OPTION_CHTVLUMABANDWIDTHCVBS,	"CHTVLumaBandwidthCVBS",	OPTV_INTEGER,	{0}, FALSE },
208    { OPTION_CHTVLUMABANDWIDTHSVIDEO,	"CHTVLumaBandwidthSVIDEO",	OPTV_INTEGER,	{0}, FALSE },
209    { OPTION_CHTVLUMAFLICKERFILTER,	"CHTVLumaFlickerFilter",	OPTV_INTEGER,	{0}, FALSE },
210    { OPTION_CHTVCHROMABANDWIDTH,	"CHTVChromaBandwidth",		OPTV_INTEGER,	{0}, FALSE },
211    { OPTION_CHTVCHROMAFLICKERFILTER,	"CHTVChromaFlickerFilter",	OPTV_INTEGER,	{0}, FALSE },
212    { OPTION_CHTVCVBSCOLOR,		"CHTVCVBSColor",		OPTV_BOOLEAN,	{0}, FALSE },
213    { OPTION_CHTVTEXTENHANCE,		"CHTVTextEnhance",		OPTV_INTEGER,	{0}, FALSE },
214    { OPTION_CHTVCONTRAST,		"CHTVContrast",			OPTV_INTEGER,	{0}, FALSE },
215    { OPTION_SISTVEDGEENHANCE,		"SISTVEdgeEnhance",		OPTV_INTEGER,	{0}, FALSE },
216    { OPTION_SISTVANTIFLICKER,		"SISTVAntiFlicker",		OPTV_STRING,	{0}, FALSE },
217    { OPTION_SISTVSATURATION,		"SISTVSaturation",		OPTV_INTEGER,	{0}, FALSE },
218    { OPTION_SISTVCHROMAFILTER,		"SISTVCFilter",			OPTV_BOOLEAN,	{0}, FALSE },
219    { OPTION_SISTVLUMAFILTER,		"SISTVYFilter",	  		OPTV_INTEGER,	{0}, FALSE },
220    { OPTION_SISTVCOLCALIBFINE,		"SISTVColorCalibFine",		OPTV_INTEGER,	{0}, FALSE },
221    { OPTION_SISTVCOLCALIBCOARSE,	"SISTVColorCalibCoarse",	OPTV_INTEGER,	{0}, FALSE },
222    { OPTION_TVXSCALE,			"SISTVXScale", 	  		OPTV_INTEGER,	{0}, FALSE },
223    { OPTION_TVYSCALE,			"SISTVYScale", 	  		OPTV_INTEGER,	{0}, FALSE },
224    { OPTION_TVXPOSOFFSET,		"TVXPosOffset", 		OPTV_INTEGER,	{0}, FALSE },
225    { OPTION_TVYPOSOFFSET,		"TVYPosOffset", 		OPTV_INTEGER,	{0}, FALSE },
226    { OPTION_SIS6326ANTIFLICKER,	"SIS6326TVAntiFlicker",		OPTV_STRING,	{0}, FALSE },
227    { OPTION_SIS6326ENABLEYFILTER,	"SIS6326TVEnableYFilter",	OPTV_BOOLEAN,	{0}, FALSE },
228    { OPTION_SIS6326YFILTERSTRONG,	"SIS6326TVYFilterStrong",	OPTV_BOOLEAN,	{0}, FALSE },
229    { OPTION_SIS6326FORCETVPPLUG,	"SIS6326TVForcePlug",		OPTV_STRING,	{0}, FALSE },
230    { OPTION_SIS6326FSCADJUST,		"SIS6326FSCAdjust",		OPTV_INTEGER,	{0}, FALSE },
231    { OPTION_YPBPRAR,			"YPbPrAspectRatio",		OPTV_STRING,	{0}, FALSE },
232    { OPTION_TVBLUE,			"TVBlueWorkAround",		OPTV_BOOLEAN,	{0}, FALSE },
233    { OPTION_USERGBCURSORBLEND,		"ColorHWCursorBlending",	OPTV_BOOLEAN,	{0}, FALSE },
234    { OPTION_USERGBCURSORBLENDTH,	"ColorHWCursorBlendThreshold",	OPTV_INTEGER,	{0}, FALSE },
235    { OPTION_DDCFORCRT2,		"CRT2Detection", 		OPTV_BOOLEAN,	{0}, FALSE },
236    { OPTION_FORCECRT2REDETECTION,	"ForceCRT2ReDetection",		OPTV_BOOLEAN,	{0}, FALSE },
237    { OPTION_SENSEYPBPR,		"SenseYPbPr",			OPTV_BOOLEAN,	{0}, FALSE },
238    { OPTION_CRT1GAMMA,			"CRT1Gamma",			OPTV_BOOLEAN,	{0}, FALSE },
239    { OPTION_CRT2GAMMA,			"CRT2Gamma",			OPTV_ANYSTR,	{0}, FALSE },
240    { OPTION_STOREDBRI,			"GammaBrightness",		OPTV_STRING,	{0}, FALSE },
241    { OPTION_STOREDBRI2,		"GammaBrightnessCRT2",		OPTV_STRING,	{0}, FALSE },
242    { OPTION_STOREDBRI2,		"CRT2GammaBrightness",		OPTV_STRING,	{0}, FALSE },
243    { OPTION_NEWSTOREDBRI,		"Brightness",			OPTV_STRING,	{0}, FALSE },
244    { OPTION_NEWSTOREDBRI,		"NewGammaBrightness",		OPTV_STRING,	{0}, FALSE },
245    { OPTION_NEWSTOREDBRI2,		"CRT2Brightness",		OPTV_STRING,	{0}, FALSE },
246    { OPTION_NEWSTOREDBRI2,		"CRT2NewGammaBrightness",	OPTV_STRING,	{0}, FALSE },
247    { OPTION_NEWSTOREDCON,		"Contrast",			OPTV_STRING,	{0}, FALSE },
248    { OPTION_NEWSTOREDCON,		"NewGammaContrast",		OPTV_STRING,	{0}, FALSE },
249    { OPTION_NEWSTOREDCON2,		"CRT2Contrast",			OPTV_STRING,	{0}, FALSE },
250    { OPTION_NEWSTOREDCON2,		"CRT2NewGammaContrast",		OPTV_STRING,	{0}, FALSE },
251    { OPTION_CRT1SATGAIN,		"CRT1Saturation", 		OPTV_INTEGER,	{0}, FALSE },
252    { OPTION_XVGAMMA,			"XvGamma", 	  		OPTV_ANYSTR,	{0}, FALSE },
253    { OPTION_XVDEFCONTRAST,		"XvDefaultContrast", 		OPTV_INTEGER,	{0}, FALSE },
254    { OPTION_XVDEFBRIGHTNESS,		"XvDefaultBrightness",		OPTV_INTEGER,	{0}, FALSE },
255    { OPTION_XVDEFHUE,			"XvDefaultHue",			OPTV_INTEGER,	{0}, FALSE },
256    { OPTION_XVDEFSATURATION,		"XvDefaultSaturation",		OPTV_INTEGER,	{0}, FALSE },
257    { OPTION_XVDEFDISABLEGFX,		"XvDefaultDisableGfx",		OPTV_BOOLEAN,	{0}, FALSE },
258    { OPTION_XVDEFDISABLEGFXLR,		"XvDefaultDisableGfxLR",	OPTV_BOOLEAN,	{0}, FALSE },
259    { OPTION_XVCHROMAMIN,		"XvChromaMin",	  		OPTV_INTEGER,	{0}, FALSE },
260    { OPTION_XVCHROMAMAX,		"XvChromaMax", 	  		OPTV_INTEGER,	{0}, FALSE },
261    { OPTION_XVUSECHROMAKEY,		"XvUseChromaKey",		OPTV_BOOLEAN,	{0}, FALSE },
262    { OPTION_XVINSIDECHROMAKEY,		"XvInsideChromaKey",		OPTV_BOOLEAN,	{0}, FALSE },
263    { OPTION_XVYUVCHROMAKEY,		"XvYUVChromaKey",		OPTV_BOOLEAN,	{0}, FALSE },
264    { OPTION_XVDISABLECOLORKEY,		"XvDisableColorKey",		OPTV_BOOLEAN,	{0}, FALSE },
265    { OPTION_XVMEMCPY,			"XvUseMemcpy",  		OPTV_BOOLEAN,	{0}, FALSE },
266    { OPTION_XVBENCHCPY,		"BenchmarkMemcpy",		OPTV_BOOLEAN,	{0}, FALSE },
267#ifndef SISCHECKOSSSE
268    { OPTION_XVSSECOPY, 		"UseSSE",  	  		OPTV_BOOLEAN,	{0}, FALSE },
269#endif
270    { OPTION_XVDEFAULTADAPTOR,		"XvDefaultAdaptor",		OPTV_STRING,	{0}, FALSE },
271    { OPTION_SCALELCD,			"ScaleLCD",	   		OPTV_BOOLEAN,	{0}, FALSE },
272    { OPTION_CENTERLCD,			"CenterLCD",	   		OPTV_BOOLEAN,	{0}, FALSE },
273    { OPTION_ENABLEHOTKEY,		"EnableHotkey",	   		OPTV_BOOLEAN,	{0}, FALSE },
274    { OPTION_FORCE1ASPECT,		"ForceCRT1VGAAspect",		OPTV_STRING,	{0}, FALSE },
275    { OPTION_FORCE2ASPECT,		"ForceCRT2VGAAspect",		OPTV_STRING,	{0}, FALSE },
276#ifdef SISMERGED
277    { OPTION_MERGEDFB,			"MergedFB",			OPTV_ANYSTR,	{0}, FALSE },
278    { OPTION_MERGEDFB,			"TwinView",			OPTV_ANYSTR,	{0}, FALSE },	/* alias */
279    { OPTION_MERGEDFBAUTO,		"MergedFBAuto",			OPTV_BOOLEAN,	{0}, FALSE },
280    { OPTION_CRT2HSYNC,			"CRT2HSync",			OPTV_STRING,	{0}, FALSE },
281    { OPTION_CRT2HSYNC,			"SecondMonitorHorizSync",	OPTV_STRING,	{0}, FALSE },   /* alias */
282    { OPTION_CRT2VREFRESH,		"CRT2VRefresh",			OPTV_STRING,	{0}, FALSE },
283    { OPTION_CRT2VREFRESH,		"SecondMonitorVertRefresh", 	OPTV_STRING,	{0}, FALSE },   /* alias */
284    { OPTION_CRT2POS,			"CRT2Position",			OPTV_STRING,	{0}, FALSE },
285    { OPTION_CRT2POS,			"TwinViewOrientation",		OPTV_STRING,	{0}, FALSE },   /* alias */
286    { OPTION_METAMODES,			"MetaModes",  			OPTV_STRING,	{0}, FALSE },
287    { OPTION_MERGEDDPI,			"MergedDPI", 			OPTV_STRING,	{0}, FALSE },
288#ifdef SISXINERAMA
289    { OPTION_SISXINERAMA,		"MergedXinerama",		OPTV_BOOLEAN,	{0}, FALSE },
290    { OPTION_SISXINERAMA,		"TwinviewXineramaInfo",		OPTV_BOOLEAN,	{0}, FALSE },   /* alias */
291    { OPTION_CRT2ISSCRN0,		"MergedXineramaCRT2IsScreen0",	OPTV_BOOLEAN,	{0}, FALSE },
292    { OPTION_MERGEDFBNONRECT,		"MergedNonRectangular",		OPTV_BOOLEAN,	{0}, FALSE },
293    { OPTION_MERGEDFBMOUSER,		"MergedMouseRestriction",	OPTV_BOOLEAN,	{0}, FALSE },
294#endif
295#endif
296#ifdef SIS_CP
297    SIS_CP_OPTION_DETAIL
298#endif
299    { -1,				NULL,				OPTV_NONE,	{0}, FALSE }
300};
301
302static int
303SiS_FIFT(const OptionInfoRec *options, int token)
304{
305    /* Find index from token */
306    int i = 0;
307    while(options[i].token >= 0) {
308       if(options[i].token == token) return i;
309       i++;
310    }
311    return 0; /* Should not happen */
312}
313
314static void
315SiS_PrintBadOpt(ScrnInfoPtr pScrn, char *strptr, int token)
316{
317    SISPtr pSiS = SISPTR(pScrn);
318
319    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
320	"\"%s\" is is not a valid parameter for option \"%s\"\n",
321	strptr, pSiS->Options[SiS_FIFT(pSiS->Options, token)].name);
322}
323
324static void
325SiS_PrintIlRange(ScrnInfoPtr pScrn, int token, int min, int max, UChar showhex)
326{
327    SISPtr pSiS = SISPTR(pScrn);
328    static const char *ilparmd = "Invalid parameter for \"%s\". Valid range is %d - %d\n";
329    static const char *ilparmh = "Invalid parameter for \"%s\". Valid range is 0x%x - 0x%x\n";
330
331    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
332	showhex ? ilparmh : ilparmd,
333	pSiS->Options[SiS_FIFT(pSiS->Options, token)].name, min, max);
334}
335
336#ifdef SISDUALHEAD
337static void
338SiS_PrintOverruleDHM(ScrnInfoPtr pScrn, int token1, int token2)
339{
340    SISPtr pSiS = SISPTR(pScrn);
341
342    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
343	"\"%s\" overrules \"%s\" in CRT2 (Master) device section\n",
344	pSiS->Options[SiS_FIFT(pSiS->Options, token1)].name,
345	pSiS->Options[SiS_FIFT(pSiS->Options, token2)].name);
346}
347#endif
348
349static Bool
350SiS_StrIsBoolOn(char *strptr)
351{
352    if( (*strptr == '\0')             ||
353	(!xf86NameCmp(strptr,"on"))   ||
354	(!xf86NameCmp(strptr,"true")) ||
355	(!xf86NameCmp(strptr,"yes"))  ||
356	(!xf86NameCmp(strptr,"1")) ) return TRUE;
357    return FALSE;
358}
359
360static Bool
361SiS_StrIsBoolOff(char *strptr)
362{
363    if( (!xf86NameCmp(strptr,"off"))   ||
364	(!xf86NameCmp(strptr,"false")) ||
365	(!xf86NameCmp(strptr,"no"))    ||
366	(!xf86NameCmp(strptr,"0")) ) return TRUE;
367    return FALSE;
368}
369
370static Bool
371SiS_EvalOneOrThreeFloats(ScrnInfoPtr pScrn, int token, const char *myerror,
372                         char *strptr, int *v1, int *v2, int *v3)
373{
374    SISPtr pSiS = SISPTR(pScrn);
375    float val1 = 0.0, val2 = 0.0, val3 = 0.0;
376    Bool valid = FALSE;
377    int result = sscanf(strptr, "%f %f %f", &val1, &val2, &val3);
378    if(result == 1) {
379       if((val1 >= 0.1) && (val1 <= 10.0)) {
380	  valid = TRUE;
381	  *v1 = *v2 = *v3 = (int)(val1 * 1000);
382       }
383    } else if(result == 3) {
384       if((val1 >= 0.1) && (val1 <= 10.0) &&
385	  (val2 >= 0.1) && (val2 <= 10.0) &&
386	  (val3 >= 0.1) && (val3 <= 10.0)) {
387	  valid = TRUE;
388	  *v1 = (int)(val1 * 1000);
389	  *v2 = (int)(val2 * 1000);
390	  *v3 = (int)(val3 * 1000);
391       }
392    }
393    if(!valid) {
394       xf86DrvMsg(pScrn->scrnIndex, X_WARNING, myerror,
395                  pSiS->Options[SiS_FIFT(pSiS->Options, token)].name);
396    }
397    return (valid);
398}
399
400static Bool
401SiS_EvalOneOrThreeFloats2(ScrnInfoPtr pScrn, int token, const char *myerror,
402                         char *strptr, float *v1, float *v2, float *v3)
403{
404    SISPtr pSiS = SISPTR(pScrn);
405    float val1 = 0.0, val2 = 0.0, val3 = 0.0;
406    Bool valid = FALSE;
407    int result = sscanf(strptr, "%f %f %f", &val1, &val2, &val3);
408    if(result == 1) {
409       if((val1 >= -1.0) && (val1 <= 1.0)) {
410	  valid = TRUE;
411	  *v1 = *v2 = *v3 = val1;
412       }
413    } else if(result == 3) {
414       if((val1 >= -1.0) && (val1 <= 1.0) &&
415	  (val2 >= -1.0) && (val2 <= 1.0) &&
416	  (val3 >= -1.0) && (val3 <= 1.0)) {
417	  valid = TRUE;
418	  *v1 = val1;
419	  *v2 = val2;
420	  *v3 = val3;
421       }
422    }
423    if(!valid) {
424       xf86DrvMsg(pScrn->scrnIndex, X_WARNING, myerror,
425                  pSiS->Options[SiS_FIFT(pSiS->Options, token)].name);
426    }
427    return (valid);
428}
429
430void
431SiSOptions(ScrnInfoPtr pScrn)
432{
433    SISPtr      pSiS = SISPTR(pScrn);
434    MessageType from;
435    char        *strptr;
436    int         ival;
437    static const char *baddhm     = "Option \"%s\" ignored in Dual Head mode\n";
438    static const char *validparm  = "Valid parameters are";
439    static const char *disabledstr= "disabled";
440    static const char *enabledstr = "enabled";
441    static const char *gammaopt   = "%s expects either a boolean, or 1 or 3 real numbers (0.1 - 10.0)\n";
442    static const char *briopt     = "%s expects 1 or 3 real numbers (0.1 - 10.0)\n";
443    static const char *newbriopt     = "%s expects 1 or 3 real numbers (-1.0 - 1.0)\n";
444    Bool        val, IsDHM = FALSE;
445    Bool	IsSecondHead = FALSE;
446
447    /* Collect all of the relevant option flags (fill in pScrn->options) */
448    xf86CollectOptions(pScrn, NULL);
449
450    /* Process the options */
451    if(!(pSiS->Options = malloc(sizeof(SISOptions)))) return;
452
453    memcpy(pSiS->Options, SISOptions, sizeof(SISOptions));
454
455    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSiS->Options);
456
457    /* Set defaults */
458
459    pSiS->newFastVram = -1;
460    pSiS->HostBus = TRUE;
461    pSiS->TurboQueue = TRUE;
462#ifdef SISVRAMQ
463    /* TODO: Option (315 series VRAM command queue) */
464    /* But beware: sisfb does not know about this!!! */
465    pSiS->cmdQueueSize = 512*1024;
466    if(pSiS->ChipType == XGI_20) {
467       /* Hardware maximum on Z7: 128k */
468       pSiS->cmdQueueSize = 128*1024;
469    }
470#endif
471    pSiS->doRender = TRUE;
472    pSiS->HWCursor = TRUE;
473    pSiS->Rotate = 0;
474    pSiS->Reflect = 0;
475    pSiS->NoAccel = FALSE;
476#if (defined(SIS_USE_EXA) && defined(SIS_USE_XAA)) || !defined(SIS_USE_EXA)
477    pSiS->useEXA = FALSE;
478#else
479    pSiS->useEXA = TRUE;
480#endif
481    pSiS->ShadowFB = FALSE;
482    pSiS->loadDRI = FALSE;
483#ifdef SISDRI
484    pSiS->agpWantedPages = AGP_PAGES;
485#endif
486    pSiS->VESA = -1;
487    pSiS->NoXvideo = FALSE;
488    pSiS->maxxfbmem = 0;
489    pSiS->forceCRT1 = -1;
490    pSiS->DSTN = FALSE;
491    pSiS->FSTN = FALSE;
492    pSiS->XvOnCRT2 = FALSE;
493    pSiS->NoYV12 = -1;
494    pSiS->PDC = -1;
495    pSiS->PDCA = -1;
496    pSiS->EMI = -1;
497    pSiS->PRGB = -1;
498    pSiS->OptTVStand = -1;
499    pSiS->OptROMUsage = -1;
500    pSiS->noInternalModes = FALSE;
501    pSiS->OptUseOEM = -1;
502    pSiS->OptTVOver = -1;
503    pSiS->OptTVSOver = -1;
504    pSiS->chtvlumabandwidthcvbs = -1;
505    pSiS->chtvlumabandwidthsvideo = -1;
506    pSiS->chtvlumaflickerfilter = -1;
507    pSiS->chtvchromabandwidth = -1;
508    pSiS->chtvchromaflickerfilter = -1;
509    pSiS->chtvcvbscolor = -1;
510    pSiS->chtvtextenhance = -1;
511    pSiS->chtvcontrast = -1;
512    pSiS->sistvedgeenhance = -1;
513    pSiS->sistvantiflicker = -1;
514    pSiS->sistvsaturation = -1;
515    pSiS->sistvcfilter = -1;
516    pSiS->sistvyfilter = 1; /* 0 = off, 1 = default, 2-8 = filter no */
517    pSiS->sistvcolcalibc = 0;
518    pSiS->sistvcolcalibf = 0;
519    pSiS->sis6326enableyfilter = -1;
520    pSiS->sis6326yfilterstrong = -1;
521    pSiS->sis6326tvplug = -1;
522    pSiS->sis6326fscadjust = 0;
523    pSiS->tvxpos = 0;
524    pSiS->tvypos = 0;
525    pSiS->tvxscale = 0;
526    pSiS->tvyscale = 0;
527    pSiS->siscrt1satgain = 0;
528    pSiS->crt1satgaingiven = FALSE;
529    pSiS->NonDefaultPAL = pSiS->NonDefaultNTSC = -1;
530    pSiS->chtvtype = -1;
531    pSiS->restorebyset = TRUE;
532    pSiS->nocrt2ddcdetection = FALSE;
533    pSiS->forcecrt2redetection = TRUE;
534    pSiS->SenseYPbPr = TRUE;
535    pSiS->ForceCRT1Type = CRT1_VGA;
536    pSiS->CRT1TypeForced = FALSE;
537    pSiS->ForceCRT2Type = CRT2_DEFAULT;
538    pSiS->ForceYPbPrAR = TV_YPBPR169;
539    pSiS->ForceTVType = -1;
540    pSiS->CRT1gamma = TRUE;
541    pSiS->CRT1gammaGiven = FALSE;
542    pSiS->CRT2gamma = TRUE;
543    pSiS->XvGamma = FALSE;
544    pSiS->XvGammaGiven = FALSE;
545    pSiS->enablesisctrl = FALSE;
546    if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
547       pSiS->XvDefBri = 10;
548       pSiS->XvDefCon = 2;
549    } else {
550       pSiS->XvDefBri = 0;
551       pSiS->XvDefCon = 4;
552    }
553    pSiS->XvDefHue = 0;
554    pSiS->XvDefSat = 0;
555    pSiS->XvDefDisableGfx = FALSE;
556    pSiS->XvDefDisableGfxLR = FALSE;
557    pSiS->XvDefAdaptorBlit = FALSE;
558    pSiS->UsePanelScaler = -1;
559    pSiS->CenterLCD = -1;
560    pSiS->XvUseMemcpy = TRUE;
561    pSiS->XvUseChromaKey = FALSE;
562    pSiS->XvDisableColorKey = FALSE;
563    pSiS->XvInsideChromaKey = FALSE;
564    pSiS->XvYUVChromaKey = FALSE;
565    pSiS->XvChromaMin = 0x000101fe;
566    pSiS->XvChromaMax = 0x000101ff;
567    pSiS->XvGammaRed = pSiS->XvGammaGreen = pSiS->XvGammaBlue =
568          pSiS->XvGammaRedDef = pSiS->XvGammaGreenDef = pSiS->XvGammaBlueDef = 1000;
569    pSiS->GammaBriR = pSiS->GammaBriG = pSiS->GammaBriB = 1000;
570    pSiS->CRT2SepGamma = FALSE;
571    pSiS->GammaR2 = pSiS->GammaG2 = pSiS->GammaB2 = 1.0;
572    pSiS->GammaBriR2 = pSiS->GammaBriG2 = pSiS->GammaBriB2 = 1000;
573    pSiS->NewGammaBriR = pSiS->NewGammaBriG = pSiS->NewGammaBriB = 0.0;
574    pSiS->NewGammaConR = pSiS->NewGammaConG = pSiS->NewGammaConB = 0.0;
575    pSiS->NewGammaBriR2 = pSiS->NewGammaBriG2 = pSiS->NewGammaBriB2 = 0.0;
576    pSiS->NewGammaConR2 = pSiS->NewGammaConG2 = pSiS->NewGammaConB2 = 0.0;
577    pSiS->HideHWCursor = FALSE;
578    pSiS->HWCursorIsVisible = FALSE;
579    pSiS->OverruleRanges = TRUE;
580    pSiS->BenchMemCpy = TRUE;
581#ifndef SISCHECKOSSSE
582    pSiS->XvSSEMemcpy = FALSE;
583#endif
584#ifdef SISMERGED
585    pSiS->MergedFB = pSiS->MergedFBAuto = FALSE;
586    pSiS->CRT2Position = sisRightOf;
587    pSiS->CRT2HSync = NULL;
588    pSiS->CRT2VRefresh = NULL;
589    pSiS->MetaModes = NULL;
590    pSiS->MergedFBXDPI = pSiS->MergedFBYDPI = 0;
591    pSiS->CRT1XOffs = pSiS->CRT1YOffs = pSiS->CRT2XOffs = pSiS->CRT2YOffs = 0;
592    pSiS->NonRect = pSiS->HaveNonRect = pSiS->HaveOffsRegions = FALSE;
593    pSiS->MBXNR1XMAX = pSiS->MBXNR1YMAX = pSiS->MBXNR2XMAX = pSiS->MBXNR2YMAX = 65536;
594    pSiS->MouseRestrictions = TRUE;
595#ifdef SISXINERAMA
596    pSiS->UseSiSXinerama = TRUE;
597    pSiS->CRT2IsScrn0 = FALSE;
598#endif
599#endif
600#ifdef SIS_CP
601    SIS_CP_OPT_DEFAULT
602#endif
603
604    /* Chipset dependent defaults */
605
606    if(pSiS->Chipset == PCI_CHIP_SIS530) {
607       /* TQ still broken on 530/620? */
608       pSiS->TurboQueue = FALSE;
609    }
610
611    if(pSiS->Chipset == PCI_CHIP_SIS6326) {
612       pSiS->newFastVram = 1;
613    }
614
615    if(pSiS->ChipType == SIS_315H ||
616       pSiS->ChipType == SIS_315) {
617       /* Cursor engine seriously broken */
618       pSiS->HWCursor = FALSE;
619    }
620
621    if((pSiS->Chipset == PCI_CHIP_SIS550) ||
622       (pSiS->Chipset == PCI_CHIP_XGIXG20)) {
623       /* Alpha blending not supported */
624       pSiS->doRender = FALSE;
625    }
626
627    if(pSiS->Chipset == PCI_CHIP_XGIXG20) {
628       /* No video overlay, no video blitter */
629       pSiS->NoXvideo = TRUE;
630    }
631
632    /* DRI only supported on 300 series,
633     * so don't load DRI by default on
634     * others.
635     */
636    if(pSiS->VGAEngine == SIS_300_VGA) {
637       pSiS->loadDRI = TRUE;
638    }
639
640#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
641    pSiS->OptUseColorCursor = 0;
642#else
643    if(pSiS->VGAEngine == SIS_300_VGA) {
644       pSiS->OptUseColorCursor = 0;
645       pSiS->OptUseColorCursorBlend = 1;
646       pSiS->OptColorCursorBlendThreshold = 0x37000000;
647    } else if(pSiS->VGAEngine == SIS_315_VGA) {
648       if(pSiS->Chipset == PCI_CHIP_XGIXG20) {
649          /* No color HW cursor on Z7 */
650          pSiS->OptUseColorCursor = 0;
651       } else {
652          pSiS->OptUseColorCursor = 1;
653       }
654    }
655#endif
656
657    if(pSiS->VGAEngine == SIS_300_VGA) {
658       pSiS->AllowHotkey = 0;
659    } else if(pSiS->VGAEngine == SIS_315_VGA) {
660       pSiS->AllowHotkey = 1;
661    }
662
663    /* Collect the options */
664
665    /* FastVRAM (5597/5598, 6326 and 530/620 only)
666     */
667    if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
668       from = X_DEFAULT;
669       if(xf86GetOptValBool(pSiS->Options, OPTION_FAST_VRAM, &pSiS->newFastVram)) {
670          from = X_CONFIG;
671       }
672       xf86DrvMsg(pScrn->scrnIndex, from, "Fast VRAM timing %s\n",
673		   (pSiS->newFastVram == -1) ?
674			 ((pSiS->oldChipset == OC_SIS620) ? "enabled (for read only)" :
675							    "enabled (for write only)") :
676			 (pSiS->newFastVram ? "enabled (for read and write)" : disabledstr));
677    }
678
679    /* HostBus (5597/5598 only)
680     */
681    if(pSiS->Chipset == PCI_CHIP_SIS5597) {
682       from = X_DEFAULT;
683       if(xf86GetOptValBool(pSiS->Options, OPTION_HOSTBUS, &pSiS->HostBus)) {
684          from = X_CONFIG;
685       }
686       xf86DrvMsg(pScrn->scrnIndex, from, "SiS5597/5598 VGA-to-CPU host bus %s\n",
687                   pSiS->HostBus ? enabledstr : disabledstr);
688    }
689
690    /* MaxXFBMem
691     * This options limits the amount of video memory X uses for screen
692     * and off-screen buffers. This option should be used if using DRI
693     * is intended. The kernel framebuffer driver required for DRM will
694     * start its memory heap at 12MB if it detects more than 16MB, at 8MB if
695     * between 8 and 16MB are available, otherwise at 4MB. So, if the amount
696     * of memory X uses, a clash between the framebuffer's memory heap
697     * and X is avoided. The amount is to be specified in KB.
698     */
699    if(xf86GetOptValInteger(pSiS->Options, OPTION_MAXXFBMEM, (int *)&pSiS->maxxfbmem)) {
700       if(pSiS->maxxfbmem >= 2048) {
701	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
702		   "MaxXFBMem: Framebuffer memory shall be limited to %d KB\n",
703		    pSiS->maxxfbmem);
704	  pSiS->maxxfbmem *= 1024;
705       } else {
706	  pSiS->maxxfbmem = 0;
707	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
708		   "Invalid MaxXFBMem setting; minimum is 2048\n");
709       }
710    }
711
712    /* Accel
713     * Turns on/off 2D acceleration
714     */
715    if(!xf86ReturnOptValBool(pSiS->Options, OPTION_ACCEL, TRUE)) {
716       pSiS->NoAccel = TRUE;
717#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
718       pSiS->NoXvideo = TRUE;
719       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "2D Acceleration and Xv disabled\n");
720#else
721       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "2D Acceleration disabled\n");
722#endif
723    }
724
725#if defined(SIS_USE_XAA) && defined(SIS_USE_EXA)
726    if(!pSiS->NoAccel) {
727       from = X_DEFAULT;
728       if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_ACCELMETHOD))) {
729	  if(!xf86NameCmp(strptr,"XAA")) {
730	     from = X_CONFIG;
731	     pSiS->useEXA = FALSE;
732	  } else if(!xf86NameCmp(strptr,"EXA")) {
733	     from = X_CONFIG;
734	     pSiS->useEXA = TRUE;
735	  }
736       }
737       xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n",
738		pSiS->useEXA ? "EXA" : "XAA");
739    }
740#endif
741
742    /* RenderAcceleration
743     * En/Disables RENDER acceleration (315/330/340 series only, not 550, not XGI Z7)
744     */
745#ifdef SIS_USE_XAA
746    if((pSiS->VGAEngine == SIS_315_VGA)   &&
747       (pSiS->Chipset != PCI_CHIP_SIS550) &&
748       (pSiS->Chipset != PCI_CHIP_XGIXG20) &&
749       (!pSiS->NoAccel)) {
750       if(xf86GetOptValBool(pSiS->Options, OPTION_RENDER, &pSiS->doRender)) {
751	  if(!pSiS->doRender) {
752	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "RENDER Acceleration disabled\n");
753	  }
754       }
755    }
756#else
757    pSiS->doRender = FALSE;
758#endif
759
760    /* SWCursor, HWCursor
761     * Chooses whether to use the hardware or software cursor
762     */
763    from = X_DEFAULT;
764    if(xf86GetOptValBool(pSiS->Options, OPTION_HW_CURSOR, &pSiS->HWCursor)) {
765       from = X_CONFIG;
766    }
767    if(xf86ReturnOptValBool(pSiS->Options, OPTION_SW_CURSOR, FALSE)) {
768       from = X_CONFIG;
769       pSiS->HWCursor = FALSE;
770       pSiS->OptUseColorCursor = 0;
771    }
772    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
773                                pSiS->HWCursor ? "HW" : "SW");
774
775    /*
776     * UseColorHWCursor
777     * ColorHWCursorBlending
778     * ColorHWCursorBlendThreshold
779     *
780     * Enable/disable color hardware cursors;
781     * enable/disable color hw cursor emulation for 300 series
782     * select emultation transparency threshold for 300 series
783     *
784     */
785#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
786#ifdef ARGB_CURSOR
787#ifdef SIS_ARGB_CURSOR
788    if((pSiS->HWCursor) &&
789       ((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) &&
790       (pSiS->Chipset != PCI_CHIP_XGIXG20)) {
791
792       from = X_DEFAULT;
793       if(xf86GetOptValBool(pSiS->Options, OPTION_USERGBCURSOR, &pSiS->OptUseColorCursor)) {
794	  from = X_CONFIG;
795       }
796       xf86DrvMsg(pScrn->scrnIndex, from, "Color HW cursor is %s\n",
797	            pSiS->OptUseColorCursor ? enabledstr : disabledstr);
798
799       if(pSiS->VGAEngine == SIS_300_VGA) {
800	  from = X_DEFAULT;
801	  if(xf86GetOptValBool(pSiS->Options, OPTION_USERGBCURSORBLEND, &pSiS->OptUseColorCursorBlend)) {
802	     from = X_CONFIG;
803	  }
804	  if(pSiS->OptUseColorCursor) {
805	     xf86DrvMsg(pScrn->scrnIndex, from,
806		"HW cursor color blending emulation is %s\n",
807		(pSiS->OptUseColorCursorBlend) ? enabledstr : disabledstr);
808	  }
809	  from = X_DEFAULT;
810	  if(xf86GetOptValInteger(pSiS->Options, OPTION_USERGBCURSORBLENDTH, &ival)) {
811	     if((ival >= 0) && (ival <= 255)) {
812		from = X_CONFIG;
813		pSiS->OptColorCursorBlendThreshold = (ival << 24);
814	     } else {
815		ival = pSiS->OptColorCursorBlendThreshold >> 24;
816		SiS_PrintIlRange(pScrn, OPTION_USERGBCURSORBLENDTH, 0, 255, 0);
817	     }
818	  } else {
819	     ival = pSiS->OptColorCursorBlendThreshold >> 24;
820          }
821	  if(pSiS->OptUseColorCursor) {
822	     if(pSiS->OptUseColorCursorBlend) {
823		xf86DrvMsg(pScrn->scrnIndex, from,
824		   "HW cursor color blending emulation threshold is %d\n", ival);
825	     }
826	  }
827       }
828    }
829#endif
830#endif
831#endif
832
833    /* OverruleFrequencyRanges
834     * Enable/disable overruling bogus frequency ranges for TV and LCD(A)
835     */
836    if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
837       if(xf86GetOptValBool(pSiS->Options, OPTION_OVERRULERANGES, &val)) {
838	  if(!val) {
839	     pSiS->OverruleRanges = FALSE;
840	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overruling frequency ranges disabled\n");
841	  }
842       }
843    }
844
845#ifdef SISDUALHEAD
846    if(pSiS->DualHeadMode) {
847       IsDHM = TRUE;
848       if(pSiS->SecondHead) IsSecondHead = TRUE;
849    }
850#endif
851
852    /* MergedFB
853     * Enable/disable and configure merged framebuffer mode
854     */
855#ifdef SISMERGED
856#ifdef SISDUALHEAD
857    if(pSiS->DualHeadMode) {
858       if(xf86IsOptionSet(pSiS->Options, OPTION_MERGEDFB)) {
859	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING, baddhm,
860	     pSiS->Options[SiS_FIFT(pSiS->Options, OPTION_MERGEDFB)].name);
861       }
862       if(xf86IsOptionSet(pSiS->Options, OPTION_MERGEDFBAUTO)) {
863	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING, baddhm,
864	     pSiS->Options[SiS_FIFT(pSiS->Options, OPTION_MERGEDFBAUTO)].name);
865       }
866    } else
867#endif
868    if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
869       if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_MERGEDFB))) {
870	  if(SiS_StrIsBoolOn(strptr)) {
871	     pSiS->MergedFB = TRUE;
872	     pSiS->MergedFBAuto = FALSE;
873	  } else if(!xf86NameCmp(strptr, "AUTO")) {
874	     pSiS->MergedFB = TRUE;
875	     pSiS->MergedFBAuto = TRUE;
876	  }
877       }
878       if(xf86GetOptValBool(pSiS->Options, OPTION_MERGEDFBAUTO, &val)) {
879	  if(!pSiS->MergedFB) {
880	     if(val) pSiS->MergedFB = pSiS->MergedFBAuto = TRUE;
881	  } else {
882	     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
883		"Option \"MergedFB\" overrules option \"MergedFBAuto\"\n");
884	  }
885       }
886
887       if(pSiS->MergedFB) {
888	  if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2POS))) {
889	     int result;
890	     Bool valid = FALSE;
891	     char *tempstr = malloc(strlen(strptr) + 1);
892	     result = sscanf(strptr, "%s %d", tempstr, &ival);
893	     if(result >= 1) {
894		if(!xf86NameCmp(tempstr,"LeftOf")) {
895		   pSiS->CRT2Position = sisLeftOf;
896		   valid = TRUE;
897		   if(result == 2) {
898		      if(ival < 0) pSiS->CRT1YOffs = -ival;
899		      else pSiS->CRT2YOffs = ival;
900		   }
901#ifdef SISXINERAMA
902		   pSiS->CRT2IsScrn0 = TRUE;
903#endif
904		} else if(!xf86NameCmp(tempstr,"RightOf")) {
905		   pSiS->CRT2Position = sisRightOf;
906		   valid = TRUE;
907		   if(result == 2) {
908		      if(ival < 0) pSiS->CRT1YOffs = -ival;
909		      else pSiS->CRT2YOffs = ival;
910		   }
911#ifdef SISXINERAMA
912		   pSiS->CRT2IsScrn0 = FALSE;
913#endif
914		} else if(!xf86NameCmp(tempstr,"Above")) {
915		   pSiS->CRT2Position = sisAbove;
916		   valid = TRUE;
917		   if(result == 2) {
918		      if(ival < 0) pSiS->CRT1XOffs = -ival;
919		      else pSiS->CRT2XOffs = ival;
920		   }
921#ifdef SISXINERAMA
922		   pSiS->CRT2IsScrn0 = FALSE;
923#endif
924		} else if(!xf86NameCmp(tempstr,"Below")) {
925		   pSiS->CRT2Position = sisBelow;
926		   valid = TRUE;
927		   if(result == 2) {
928		      if(ival < 0) pSiS->CRT1XOffs = -ival;
929		      else pSiS->CRT2XOffs = ival;
930		   }
931#ifdef SISXINERAMA
932		   pSiS->CRT2IsScrn0 = TRUE;
933#endif
934		} else if(!xf86NameCmp(tempstr,"Clone")) {
935		   pSiS->CRT2Position = sisClone;
936		   if(result == 1) valid = TRUE;
937#ifdef SISXINERAMA
938		   pSiS->CRT2IsScrn0 = TRUE;
939#endif
940		}
941	     }
942	     if(!valid) {
943		SiS_PrintBadOpt(pScrn, strptr, OPTION_CRT2POS);
944		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
945		    "%s \"RightOf\", \"LeftOf\", \"Above\", \"Below\", or \"Clone\"\n", validparm);
946		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
947		    "Except for \"Clone\", the parameter may be followed by an integer.\n");
948	     }
949	     free(tempstr);
950	  }
951	  if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_METAMODES))) {
952	     pSiS->MetaModes = malloc(strlen(strptr) + 1);
953	     if(pSiS->MetaModes) memcpy(pSiS->MetaModes, strptr, strlen(strptr) + 1);
954	  }
955	  if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2HSYNC))) {
956	     pSiS->CRT2HSync = malloc(strlen(strptr) + 1);
957	     if(pSiS->CRT2HSync) memcpy(pSiS->CRT2HSync, strptr, strlen(strptr) + 1);
958	  }
959	  if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2VREFRESH))) {
960	     pSiS->CRT2VRefresh = malloc(strlen(strptr) + 1);
961	     if(pSiS->CRT2VRefresh) memcpy(pSiS->CRT2VRefresh, strptr, strlen(strptr) + 1);
962	  }
963	  if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_MERGEDDPI))) {
964	     int val1 = 0, val2 = 0;
965	     sscanf(strptr, "%d %d", &val1, &val2);
966	     if(val1 && val2) {
967		pSiS->MergedFBXDPI = val1;
968		pSiS->MergedFBYDPI = val2;
969	     } else {
970		SiS_PrintBadOpt(pScrn, strptr, OPTION_MERGEDDPI);
971	     }
972	  }
973#ifdef SISXINERAMA
974	  if(pSiS->MergedFB) {
975	     if(xf86GetOptValBool(pSiS->Options, OPTION_SISXINERAMA, &val)) {
976		if(!val) pSiS->UseSiSXinerama = FALSE;
977	     }
978	     if(pSiS->UseSiSXinerama) {
979		if(xf86GetOptValBool(pSiS->Options, OPTION_CRT2ISSCRN0, &val)) {
980		   pSiS->CRT2IsScrn0 = val ? TRUE : FALSE;
981		}
982		if(xf86GetOptValBool(pSiS->Options, OPTION_MERGEDFBNONRECT, &val)) {
983		   pSiS->NonRect = val ? TRUE : FALSE;
984		}
985		if(xf86GetOptValBool(pSiS->Options, OPTION_MERGEDFBMOUSER, &val)) {
986		   pSiS->MouseRestrictions = val ? TRUE : FALSE;
987		}
988	     }
989	  }
990#endif
991       }
992    }
993#endif
994
995    /* Some options can only be specified in the Master Head's Device
996     * section. Here we give the user a hint in the log.
997     */
998#ifdef SISDUALHEAD
999    if((pSiS->DualHeadMode) && (pSiS->SecondHead)) {
1000       static const char *mystring = "Option \"%s\" only accepted in CRT2 (Master) Device section\n";
1001       int i;
1002       const short forbiddenopts[] = {
1003		OPTION_TURBOQUEUE, OPTION_RESTOREBYSET, OPTION_ENABLEHOTKEY,
1004		OPTION_ENABLESISCTRL, OPTION_USEROMDATA, OPTION_USEOEM,
1005		OPTION_FORCECRT1, OPTION_DDCFORCRT2, OPTION_FORCECRT2REDETECTION,
1006		OPTION_SENSEYPBPR, OPTION_FORCE_CRT1TYPE, OPTION_FORCE_CRT2TYPE,
1007		OPTION_YPBPRAR, OPTION_SCALELCD, OPTION_CENTERLCD, OPTION_PDC,
1008		OPTION_PDCA, OPTION_EMI, OPTION_SPECIALTIMING, OPTION_LVDSHL,
1009		OPTION_TVSTANDARD, OPTION_CHTVTYPE, OPTION_CHTVOVERSCAN,
1010		OPTION_CHTVSOVERSCAN, OPTION_CHTVLUMABANDWIDTHCVBS,
1011		OPTION_CHTVLUMABANDWIDTHSVIDEO, OPTION_CHTVLUMAFLICKERFILTER,
1012		OPTION_CHTVCHROMABANDWIDTH, OPTION_CHTVCHROMAFLICKERFILTER,
1013		OPTION_CHTVCVBSCOLOR, OPTION_CHTVTEXTENHANCE, OPTION_CHTVCONTRAST,
1014		OPTION_SISTVEDGEENHANCE, OPTION_SISTVANTIFLICKER, OPTION_SISTVSATURATION,
1015		OPTION_SISTVCHROMAFILTER, OPTION_SISTVLUMAFILTER, OPTION_SISTVCOLCALIBCOARSE,
1016		OPTION_SISTVCOLCALIBFINE, OPTION_TVXPOSOFFSET, OPTION_TVYPOSOFFSET,
1017		OPTION_TVXSCALE, OPTION_TVYSCALE, OPTION_TVBLUE, OPTION_CRT2GAMMA, OPTION_XVONCRT2,
1018		OPTION_XVDEFAULTADAPTOR, OPTION_XVMEMCPY, OPTION_XVBENCHCPY, OPTION_FORCE2ASPECT,
1019#if defined(SIS_USE_XAA) && defined(SIS_USE_EXA)
1020		OPTION_ACCELMETHOD,
1021#endif
1022#ifndef SISCHECKOSSSE
1023		OPTION_XVSSECOPY,
1024#endif
1025#ifdef SIS_CP
1026		SIS_CP_OPT_DH_WARN
1027#endif
1028		-1
1029       };
1030
1031       i = 0;
1032       while(forbiddenopts[i] >= 0) {
1033	  if(xf86IsOptionSet(pSiS->Options, (int)forbiddenopts[i])) {
1034	     xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring,
1035			pSiS->Options[SiS_FIFT(pSiS->Options, (int)forbiddenopts[i])].name);
1036	  }
1037	  i++;
1038       }
1039
1040    } else
1041#endif
1042    {
1043       if(pSiS->VGAEngine == SIS_315_VGA) {
1044
1045#ifdef SISVRAMQ
1046          xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using VRAM command queue, size %dk\n",
1047		pSiS->cmdQueueSize / 1024);
1048#else
1049	  xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using MMIO command queue, size 512k\n");
1050#endif
1051
1052       } else {
1053
1054	  /* TurboQueue */
1055	  from = X_DEFAULT;
1056	  if(xf86GetOptValBool(pSiS->Options, OPTION_TURBOQUEUE, &pSiS->TurboQueue)) {
1057	     from = X_CONFIG;
1058	  }
1059	  xf86DrvMsg(pScrn->scrnIndex, from, "TurboQueue %s\n",
1060		     pSiS->TurboQueue ? enabledstr : disabledstr);
1061       }
1062
1063       if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
1064
1065	  /* RestoreBySetMode (300/315/330 series only)
1066	   * Set this to force the driver to set the old mode instead of restoring
1067	   * the register contents. This can be used to overcome problems with
1068	   * LCD panels and video bridges.
1069	   */
1070	  if(xf86GetOptValBool(pSiS->Options, OPTION_RESTOREBYSET, &val)) {
1071	     pSiS->restorebyset = val ? TRUE : FALSE;
1072	  }
1073
1074	  /* EnableHotkey (300/315/330 series and later only)
1075	   * Enables or disables the BIOS hotkey switch for
1076	   * switching the output device on laptops.
1077	   * This key causes a total machine hang on many 300 series
1078	   * machines, it is therefore by default disabled on such.
1079	   * In dual head mode, using the hotkey is lethal, so we
1080	   * forbid it then in any case.
1081	   * However, although the driver disables the hotkey as
1082	   * BIOS developers intented to do that, some buggy BIOSes
1083	   * still cause the machine to freeze. Hence the warning.
1084	   */
1085	  ival = 0;
1086	  from = X_DEFAULT;
1087#ifdef SISDUALHEAD
1088	  if(pSiS->DualHeadMode) {
1089	     pSiS->AllowHotkey = 0;
1090	     ival = 1;
1091	  } else
1092#endif
1093	  if(xf86GetOptValBool(pSiS->Options, OPTION_ENABLEHOTKEY, &val)) {
1094	     pSiS->AllowHotkey = val ? 1 : 0;
1095	     from = X_CONFIG;
1096	  }
1097	  xf86DrvMsg(pScrn->scrnIndex, from, "Hotkey display switching is %s%s\n",
1098		pSiS->AllowHotkey ? enabledstr : disabledstr,
1099		ival ? " in dual head mode" : "");
1100	  if(pSiS->Chipset == PCI_CHIP_SIS630 ||
1101	     pSiS->Chipset == PCI_CHIP_SIS650 ||
1102	     pSiS->Chipset == PCI_CHIP_SIS660) {
1103	     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1104		 "WARNING: Using the Hotkey might freeze your machine, regardless\n");
1105	     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1106		 "         whether enabled or disabled. This is no driver bug.\n");
1107	  }
1108
1109	  /* UseROMData (300/315/330 series and later only)
1110	   * This option is enabling/disabling usage of some machine
1111	   * specific data from the BIOS ROM. This option can - and
1112	   * should - be used in case the driver makes problems
1113	   * because SiS changed the location of this data.
1114	   */
1115	  if(xf86GetOptValBool(pSiS->Options, OPTION_USEROMDATA, &val)) {
1116	     pSiS->OptROMUsage = val ? 1 : 0;
1117	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1118		 "Video ROM data usage shall be %s\n",
1119		  val ? enabledstr : disabledstr);
1120	  }
1121
1122	  /* UseOEMData (300/315/330 series and later only)
1123	   * The driver contains quite a lot data for OEM LCD panels
1124	   * and TV connector specifics which override the defaults.
1125	   * If this data is incorrect, the TV may lose color and
1126	   * the LCD panel might show some strange effects. Use this
1127	   * option to disable the usage of this data.
1128	   */
1129	  if(xf86GetOptValBool(pSiS->Options, OPTION_USEOEM, &val)) {
1130	     pSiS->OptUseOEM = val ? 1 : 0;
1131	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1132		 "Internal CRT2 OEM data usage shall be %s\n",
1133		 val ? enabledstr : disabledstr);
1134	  }
1135
1136	  /* CRT2DDCDetection (315/330 series and later only)
1137	   * If set to true, this disables CRT2 detection using DDC. This is
1138	   * to avoid problems with not entirely DDC compiant LCD panels or
1139	   * VGA monitors connected to the secondary VGA plug. Since LCD and
1140	   * VGA share the same DDC channel, it might in some cases be impossible
1141	   * to determine if the device is a CRT monitor or a flat panel.
1142	   */
1143	  if(xf86GetOptValBool(pSiS->Options, OPTION_DDCFORCRT2, &val)) {
1144	     pSiS->nocrt2ddcdetection = val ? FALSE : TRUE;
1145	  }
1146
1147	  /* ForceCRT2ReDetection (315/330 series and later only)
1148	   * If set to true, it forces re-detection of the LCD panel and
1149	   * a secondary VGA connection even if the BIOS already had found
1150	   * about it. This is meant for custom panels (ie such with
1151	   * non-standard resolutions) which the BIOS will "detect" according
1152	   * to the established timings, resulting in only a very vague idea
1153	   * about the panels real resolution. As for secondary VGA, this
1154	   * enables us to include a Plasma panel's proprietary modes.
1155	   */
1156	  if(xf86GetOptValBool(pSiS->Options, OPTION_FORCECRT2REDETECTION, &val)) {
1157	     if(val) {
1158		pSiS->forcecrt2redetection = TRUE;
1159		pSiS->nocrt2ddcdetection = FALSE;
1160	     } else
1161	        pSiS->forcecrt2redetection = FALSE;
1162	  }
1163
1164	  /* SenseYPbPr (315/330 series and later only)
1165	   * If set to true, the driver will sense for YPbPr TV. This is
1166	   * inconvenient for folks connecting SVideo and CVBS at the same
1167	   * time, because this condition will be detected as YPbPr (since
1168	   * the TV output pins are shared). "False" will not sense for
1169	   * YPbPr and detect SVideo or CVBS only.
1170	   */
1171	  if(xf86GetOptValBool(pSiS->Options, OPTION_SENSEYPBPR, &val)) {
1172	     if(val) pSiS->SenseYPbPr = TRUE;
1173	     else    pSiS->SenseYPbPr = FALSE;
1174	  }
1175
1176	  /* ForceCRT1Type (315/330 series and later only)
1177	   * Used for forcing the driver to initialize CRT1 as
1178	   * VGA (analog) or LCDA (for simultanious LCD and TV
1179	   * display) - on M650/651 and 661 or later with 301C/30xLV only!
1180	   */
1181	  if(pSiS->VGAEngine == SIS_315_VGA) {
1182	     if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_FORCE_CRT1TYPE))) {
1183		if((!xf86NameCmp(strptr,"VGA")) || (!xf86NameCmp(strptr,"CRT"))) {
1184		   pSiS->ForceCRT1Type = CRT1_VGA;
1185		   pSiS->CRT1TypeForced = TRUE;
1186		} else if( (!xf86NameCmp(strptr,"LCD"))   ||
1187			   (!xf86NameCmp(strptr,"LCDA"))  ||
1188			   (!xf86NameCmp(strptr,"DVI-D")) ||
1189			   (!xf86NameCmp(strptr,"DVID"))  ||
1190			   (!xf86NameCmp(strptr,"DVI"))   ||
1191			   (!xf86NameCmp(strptr,"LCD-A")) ) {
1192		   pSiS->ForceCRT1Type = CRT1_LCDA;
1193		   pSiS->CRT1TypeForced = TRUE;
1194		} else if((!xf86NameCmp(strptr,"NONE")) || (!xf86NameCmp(strptr,"OFF"))) {
1195		   pSiS->ForceCRT1Type = CRT1_VGA;
1196		   pSiS->forceCRT1 = 0;
1197		   pSiS->CRT1TypeForced = TRUE;
1198		} else {
1199		   SiS_PrintBadOpt(pScrn, strptr, OPTION_FORCE_CRT1TYPE);
1200		   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1201		       "%s \"VGA\" (alias \"CRT\"), \"LCD\" (alias \"DVI-D\") or NONE\n", validparm);
1202		}
1203	     }
1204	  }
1205
1206	  /* ForceCRT1 (300/315/330 series and later only)
1207	   * This option can be used to force CRT1 (VGA) to be switched on/off. Its
1208	   * intention is mainly for old monitors that can't be detected
1209	   * automatically. This is only useful on machines with a video bridge.
1210	   * In normal cases, this option won't be necessary.
1211	   */
1212	  if(pSiS->ForceCRT1Type == CRT1_VGA) {
1213	     if(xf86GetOptValBool(pSiS->Options, OPTION_FORCECRT1, &val)) {
1214		pSiS->forceCRT1 = val ? 1 : 0;
1215		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1216			"CRT1 shall be forced %s\n",
1217			val ? "ON" : "OFF");
1218	     }
1219	  }
1220
1221	  /* ForceCRT2Type (300/315/330 series and later only)
1222	   * Used for forcing the driver to use a given CRT2 device type.
1223	   * (SVIDEO, COMPOSITE and SCART for overriding detection)
1224	   */
1225	  strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_FORCE_CRT2TYPE);
1226	  if(strptr != NULL) {
1227	     if(!xf86NameCmp(strptr,"TV"))
1228		pSiS->ForceCRT2Type = CRT2_TV;
1229	     else if( (!xf86NameCmp(strptr,"SVIDEO")) ||
1230		      (!xf86NameCmp(strptr,"SVHS")) ) {
1231		pSiS->ForceCRT2Type = CRT2_TV;
1232		pSiS->ForceTVType = TV_SVIDEO;
1233             } else if( (!xf86NameCmp(strptr,"COMPOSITE")) ||
1234			(!xf86NameCmp(strptr,"CVBS")) ) {
1235		pSiS->ForceCRT2Type = CRT2_TV;
1236		pSiS->ForceTVType = TV_AVIDEO;
1237	     } else if( (!xf86NameCmp(strptr,"COMPOSITE SVIDEO")) || /* Ugly, but shorter than a parsing function */
1238			(!xf86NameCmp(strptr,"COMPOSITE+SVIDEO")) ||
1239			(!xf86NameCmp(strptr,"SVIDEO+COMPOSITE")) ||
1240			(!xf86NameCmp(strptr,"SVIDEO COMPOSITE")) ) {
1241		pSiS->ForceCRT2Type = CRT2_TV;
1242		pSiS->ForceTVType = (TV_SVIDEO | TV_AVIDEO);
1243	     } else if(!xf86NameCmp(strptr,"SCART")) {
1244		pSiS->ForceCRT2Type = CRT2_TV;
1245		pSiS->ForceTVType = TV_SCART;
1246	     } else if((!xf86NameCmp(strptr,"LCD")) || (!xf86NameCmp(strptr,"DVI-D"))) {
1247		if(pSiS->ForceCRT1Type == CRT1_VGA) {
1248		   pSiS->ForceCRT2Type = CRT2_LCD;
1249		} else {
1250		   pSiS->ForceCRT2Type = 0;
1251		   xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1252		      "Can't set both CRT1 and CRT2 type to LCD; CRT2 disabled\n");
1253		}
1254	     } else if((!xf86NameCmp(strptr,"VGA")) ||
1255		       (!xf86NameCmp(strptr,"DVI-A")) ||
1256		       (!xf86NameCmp(strptr,"CRT"))) {
1257		if(pSiS->ForceCRT1Type == CRT1_VGA) {
1258		   pSiS->ForceCRT2Type = CRT2_VGA;
1259		} else {
1260		   pSiS->ForceCRT2Type = 0;
1261		   xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1262		      "CRT2 can only be TV or off while CRT1 is LCD; CRT2 disabled\n");
1263		}
1264	     } else if(!xf86NameCmp(strptr,"NONE"))
1265		pSiS->ForceCRT2Type = 0;
1266	     else if((!xf86NameCmp(strptr,"DSTN")) && (pSiS->Chipset == PCI_CHIP_SIS550)) {
1267		if(pSiS->ForceCRT1Type == CRT1_VGA) {
1268		   pSiS->ForceCRT2Type = CRT2_LCD;
1269		   pSiS->DSTN = TRUE;
1270		}
1271	     } else if((!xf86NameCmp(strptr,"FSTN")) && (pSiS->Chipset == PCI_CHIP_SIS550)) {
1272		if(pSiS->ForceCRT1Type == CRT1_VGA) {
1273		   pSiS->ForceCRT2Type = CRT2_LCD;
1274		   pSiS->FSTN = TRUE;
1275		}
1276#ifdef ENABLE_YPBPR
1277	     } else if(!xf86NameCmp(strptr,"HIVISION")) {
1278		pSiS->ForceCRT2Type = CRT2_TV;
1279		pSiS->ForceTVType = TV_HIVISION;
1280	     } else if((!xf86NameCmp(strptr,"YPBPR1080I")) && (pSiS->VGAEngine == SIS_315_VGA)) {
1281		pSiS->ForceCRT2Type = CRT2_TV;
1282		pSiS->ForceTVType = TV_YPBPR;
1283		pSiS->ForceYPbPrType = TV_YPBPR1080I;
1284	     } else if(((!xf86NameCmp(strptr,"YPBPR525I")) || (!xf86NameCmp(strptr,"YPBPR480I"))) &&
1285		       (pSiS->VGAEngine == SIS_315_VGA)) {
1286		pSiS->ForceCRT2Type = CRT2_TV;
1287		pSiS->ForceTVType = TV_YPBPR;
1288		pSiS->ForceYPbPrType = TV_YPBPR525I;
1289	     } else if(((!xf86NameCmp(strptr,"YPBPR525P")) || (!xf86NameCmp(strptr,"YPBPR480P"))) &&
1290		       (pSiS->VGAEngine == SIS_315_VGA)) {
1291		pSiS->ForceCRT2Type = CRT2_TV;
1292		pSiS->ForceTVType = TV_YPBPR;
1293		pSiS->ForceYPbPrType = TV_YPBPR525P;
1294	     } else if(((!xf86NameCmp(strptr,"YPBPR625I")) || (!xf86NameCmp(strptr,"YPBPR576I"))) &&
1295		       (pSiS->VGAEngine == SIS_315_VGA)) {
1296		pSiS->ForceCRT2Type = CRT2_TV;
1297		pSiS->ForceTVType = TV_YPBPR;
1298		pSiS->ForceYPbPrType = TV_YPBPR625I;
1299	     } else if(((!xf86NameCmp(strptr,"YPBPR625P")) || (!xf86NameCmp(strptr,"YPBPR576P"))) &&
1300		       (pSiS->VGAEngine == SIS_315_VGA)) {
1301		pSiS->ForceCRT2Type = CRT2_TV;
1302		pSiS->ForceTVType = TV_YPBPR;
1303		pSiS->ForceYPbPrType = TV_YPBPR625P;
1304	     } else if(((!xf86NameCmp(strptr,"YPBPR750P")) || (!xf86NameCmp(strptr,"YPBPR720P"))) &&
1305	               (pSiS->VGAEngine == SIS_315_VGA)) {
1306		pSiS->ForceCRT2Type = CRT2_TV;
1307		pSiS->ForceTVType = TV_YPBPR;
1308		pSiS->ForceYPbPrType = TV_YPBPR750P;
1309#endif
1310	     } else {
1311		SiS_PrintBadOpt(pScrn, strptr, OPTION_FORCE_CRT2TYPE);
1312		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1313		    "%s \"LCD\" (=\"DVI-D\"), \"TV\", \"SVIDEO\", \"COMPOSITE\",\n"
1314		    "\t\"SVIDEO+COMPOSITE\", \"SCART\", \"VGA\" (=\"DVI-A\") or \"NONE\"; on the SiS550\n"
1315		    "\talso \"DSTN\" and \"FSTN\""
1316#ifdef ENABLE_YPBPR
1317		    				"; on SiS 301/301B bridges also \"HIVISION\", and on\n"
1318		    "\tSiS315/330/340 series with 301C/30xLV bridge also \"YPBPR480I\", \"YPBPR480P\",\n"
1319		    "\t\"YPBPR576I\", \"YPBPR576P\", \"YPBPR720P\" and \"YPBPR1080I\""
1320#endif
1321		    "\n", validparm);
1322	     }
1323
1324	     if(pSiS->ForceCRT2Type != CRT2_DEFAULT)
1325		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1326		    "CRT2 type shall be %s\n", strptr);
1327	  }
1328
1329	  if(pSiS->ForceTVType == TV_YPBPR) {
1330	     strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_YPBPRAR);
1331	     if(strptr != NULL) {
1332		if(!xf86NameCmp(strptr,"4:3LB"))
1333		   pSiS->ForceYPbPrAR = TV_YPBPR43LB;
1334		else if(!xf86NameCmp(strptr,"4:3"))
1335		   pSiS->ForceYPbPrAR = TV_YPBPR43;
1336		else if(!xf86NameCmp(strptr,"16:9"))
1337		   pSiS->ForceYPbPrAR = TV_YPBPR169;
1338		else {
1339		   SiS_PrintBadOpt(pScrn, strptr, OPTION_YPBPRAR);
1340		   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1341			"%s \"4:3LB\", \"4:3\" and \"16:9\"\n", validparm);
1342		}
1343	     }
1344	  }
1345
1346	  strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SPECIALTIMING);
1347	  if(strptr != NULL) {
1348	     int i = 0;
1349	     Bool found = FALSE;
1350	     if(!xf86NameCmp(strptr,"NONE")) {
1351		pSiS->SiS_Pr->SiS_CustomT = CUT_FORCENONE;
1352		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1353			"Special timing disabled\n");
1354	     } else {
1355	        while(SiS_customttable[i].chipID != 0) {
1356		   if(!xf86NameCmp(strptr,SiS_customttable[i].optionName)) {
1357		      pSiS->SiS_Pr->SiS_CustomT = SiS_customttable[i].SpecialID;
1358		      found = TRUE;
1359		      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1360			  "Special timing for %s %s forced\n",
1361			  SiS_customttable[i].vendorName, SiS_customttable[i].cardName);
1362		      break;
1363		   }
1364		   i++;
1365		}
1366		if(!found) {
1367		   SiS_PrintBadOpt(pScrn, strptr, OPTION_SPECIALTIMING);
1368		   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s:\n", validparm);
1369		   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t\"NONE\" (to disable special timings)\n");
1370		   i = 0;
1371		   while(SiS_customttable[i].chipID != 0) {
1372		      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1373				"\t\"%s\" (for %s %s)\n",
1374				SiS_customttable[i].optionName,
1375				SiS_customttable[i].vendorName,
1376				SiS_customttable[i].cardName);
1377		      i++;
1378		   }
1379		}
1380	     }
1381	  }
1382
1383	  /* EnableSiSCtrl */
1384	  /* Allow sisctrl tool to change driver settings */
1385	  from = X_DEFAULT;
1386	  if(xf86GetOptValBool(pSiS->Options, OPTION_ENABLESISCTRL, &val)) {
1387	     if(val) pSiS->enablesisctrl = TRUE;
1388	     from = X_CONFIG;
1389          }
1390	  xf86DrvMsg(pScrn->scrnIndex, from, "SiSCtrl utility interface is %s\n",
1391		pSiS->enablesisctrl ? enabledstr : disabledstr);
1392
1393	  if((from == X_DEFAULT) && (!pSiS->enablesisctrl)) {
1394	     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1395		"For information on SiSCtrl, see\n\t\thttp://www.winischhofer.eu/linuxsispart1.shtml#sisctrl\n");
1396	  }
1397
1398
1399	  /* ForceCRT1Aspect, ForceCRT2Aspect */
1400	  /* Make driver believe that a connected CRT/VGA device is 4:3 ("normal")
1401	   * or 16:9 ("wide"). Note: This affects only for real VGA (analog)
1402	   * output devices, not TV or DVI/LCD.
1403	   */
1404	  if(pSiS->VGAEngine == SIS_315_VGA) {
1405	     strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_FORCE2ASPECT);
1406	     if(strptr != NULL) {
1407		if(!xf86NameCmp(strptr,"WIDE")) {
1408		   pSiS->SiS_Pr->SiS_UseWideCRT2 = TRUE;
1409		} else if(!xf86NameCmp(strptr,"NORMAL")) {
1410		   pSiS->SiS_Pr->SiS_UseWideCRT2 = FALSE;
1411		} else {
1412		   SiS_PrintBadOpt(pScrn, strptr, OPTION_FORCE2ASPECT);
1413		   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s:\n", validparm);
1414		   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t\"NORMAL\" or \"WIDE\"\n");
1415		}
1416		/* Print status later */
1417	     }
1418	  }
1419
1420	 /* ScaleLCD (300/315/330 series and later only)
1421	  * Can be used to force the bridge/panel link to [do|not do] the
1422	  * scaling of modes lower than the panel's native resolution.
1423	  * Setting this to TRUE will force the bridge/panel link
1424	  * to scale; FALSE will rely on the panel's capabilities.
1425	  * Not supported on all machines.
1426	  */
1427	  if(xf86GetOptValBool(pSiS->Options, OPTION_SCALELCD, &val)) {
1428	     pSiS->UsePanelScaler = val ? 0 : 1;
1429	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "LCD scaling is %s\n",
1430	         pSiS->UsePanelScaler ? disabledstr : enabledstr);
1431	  }
1432
1433	 /* CenterLCD (300/315/330/later + SiS video bridge only)
1434	  * If LCD shall not be scaled, this selects whether 1:1 data
1435	  * will be sent to the output, or the image shall be centered
1436	  * on the LCD. For LVDS panels, screen will always be centered,
1437	  * since these have no built-in scaler. For TMDS, this is
1438	  * selectable. Non-centered means that the driver will pass
1439	  * 1:1 data to the output and that the panel will have to
1440	  * scale by itself (if supported by the panel).
1441	  */
1442	  if(xf86GetOptValBool(pSiS->Options, OPTION_CENTERLCD, &val)) {
1443	     pSiS->CenterLCD = val ? 1 : 0;
1444	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Non-scaled LCD output will %sbe centered\n",
1445	         pSiS->CenterLCD ? "not " : "");
1446	  }
1447
1448	 /* PanelDelayCompensation (300/315/330 series and later only)
1449	  * This might be required if the LCD panel shows "small waves"
1450	  * or wrong colors.
1451	  * The parameter is an integer, (on 300 series usually either
1452	  * 4, 32 or 24; on 315 series + LV bridge usually 3 or 51)
1453	  * Why this option? Simply because SiS did poor BIOS design.
1454	  * The PDC value depends on the very LCD panel used in a
1455	  * particular machine. For most panels, the driver is able
1456	  * to detect the correct value. However, some panels require
1457	  * a different setting. For 300 series, the value given must
1458	  * be within the mask 0x3c. For 661 and later, if must be
1459	  * within the range of 0 to 31.
1460	  */
1461	  ival = -1;
1462	  xf86GetOptValInteger(pSiS->Options, OPTION_PDC, &ival);
1463	  if(ival != -1) {
1464	     pSiS->PDC = ival;
1465	     if((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->PDC & ~0x3c)) {
1466		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1467		    "Invalid PanelDelayCompensation parameter\n");
1468		pSiS->PDC = -1;
1469	     } else {
1470		if(pSiS->VGAEngine == SIS_315_VGA) pSiS->PDC &= 0x1f;
1471		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1472		    "Panel delay compensation shall be %d (for LCD=CRT2)\n",
1473		     pSiS->PDC);
1474	     }
1475          }
1476
1477	 /* PanelDelayCompensation1 (315/330 series and later only)
1478	  * Same as above, but for LCD-via-CRT1 ("LCDA")
1479	  */
1480	  if(pSiS->VGAEngine == SIS_315_VGA) {
1481	     ival = -1;
1482	     xf86GetOptValInteger(pSiS->Options, OPTION_PDCA, &ival);
1483	     if(ival != -1) {
1484		pSiS->PDCA = ival;
1485		if(pSiS->PDCA > 0x1f) {
1486		   SiS_PrintIlRange(pScrn, OPTION_PDCA, 0, 31, 0);
1487		   pSiS->PDCA = -1;
1488		} else {
1489		   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1490			"Panel delay compensation shall be %d (for LCD=CRT1)\n",
1491			pSiS->PDCA);
1492		}
1493	     }
1494	  }
1495
1496	 /* LVDSHL (300/315/330/later series + 30xLV bridge only)
1497	  * This might be required if the LCD panel is too dark.
1498	  * The parameter is an integer from 0 to 3.
1499	  */
1500	  if(xf86GetOptValInteger(pSiS->Options, OPTION_LVDSHL, &pSiS->SiS_Pr->LVDSHL)) {
1501	     if((pSiS->SiS_Pr->LVDSHL < 0) || (pSiS->SiS_Pr->LVDSHL > 3)) {
1502		SiS_PrintIlRange(pScrn, OPTION_LVDSHL, 0, 3, 0);
1503		pSiS->SiS_Pr->LVDSHL = -1;
1504	     } else {
1505		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1506		     "LVDSHL will be %d\n",
1507		     pSiS->SiS_Pr->LVDSHL);
1508	     }
1509          }
1510
1511	 /* EMI (315/330/later series + 302LV/302ELV bridge only)
1512	  * This might be required if the LCD panel loses sync on
1513	  * mode switches. So far, this problem should not show up
1514	  * due to the auto-detection (from reading the values set
1515	  * by the BIOS; however, the BIOS values are wrong sometimes
1516	  * such as in the case of some Compal machines with a
1517	  * 1400x1050, or some Inventec(Compaq) machines with a
1518	  * 1280x1024 panel.
1519	  * The parameter is an integer from 0 to 0x60ffffff.
1520	  */
1521	  if(xf86GetOptValInteger(pSiS->Options, OPTION_EMI, &pSiS->EMI)) {
1522	     if((pSiS->EMI < 0) || (pSiS->EMI > 0x60ffffff)) {
1523		SiS_PrintIlRange(pScrn, OPTION_LVDSHL, 0, 0x60ffffff, 1);
1524		pSiS->EMI = -1;
1525	     } else {
1526		pSiS->EMI &= 0x60ffffff;
1527		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1528		     "EMI will be 0x%04x\n", pSiS->EMI);
1529	     }
1530	  }
1531
1532	 /* TVBlueWorkAround (315/later series only)
1533	  * TRUE and FALSE are two ways to work around a "blue shade" on
1534	  * TV output. This work-around is disabled by not setting the
1535	  * option. 315 series + 301B-DH only.
1536	  */
1537	  if(pSiS->VGAEngine == SIS_315_VGA) {
1538	     if(xf86GetOptValBool(pSiS->Options, OPTION_TVBLUE, &val)) {
1539	     	pSiS->SiS_Pr->SiS_TVBlue = val ? 1 : 0;
1540	     }
1541	  }
1542
1543	 /* ForcePanelRGB (300/315/330 series and later only)
1544	  * Can be used to force the bridge/panel link to assume a
1545	  * specified LCD color capability of 18 or 24 bit in cases
1546	  * where the BIOS carries incorrect information (such as in
1547	  * the case of the MSI m250).
1548	  */
1549	  if(xf86GetOptValInteger(pSiS->Options, OPTION_PRGB, &pSiS->PRGB)) {
1550	     if((pSiS->PRGB != 18 && pSiS->PRGB != 24)) {
1551		pSiS->PRGB = -1;
1552		SiS_PrintBadOpt(pScrn, strptr, OPTION_PRGB);
1553	     } else {
1554		   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1555			"LCD panel color depth is %d\n",
1556			pSiS->PRGB);
1557	     }
1558	  }
1559
1560       }
1561
1562
1563       /* TVStandard (300/315/330/later series and 6326 w/ TV only)
1564	* This option is for overriding the autodetection of
1565	* the BIOS/Jumper option for PAL / NTSC
1566	*/
1567       if((pSiS->VGAEngine == SIS_300_VGA) ||
1568	  (pSiS->VGAEngine == SIS_315_VGA) ||
1569	  ((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV))) {
1570	  strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_TVSTANDARD);
1571	  if(strptr != NULL) {
1572	     if(!xf86NameCmp(strptr,"PAL"))
1573		pSiS->OptTVStand = 1;
1574	     else if((!xf86NameCmp(strptr,"PALM")) ||
1575		     (!xf86NameCmp(strptr,"PAL-M"))) {
1576		pSiS->OptTVStand = 1;
1577		pSiS->NonDefaultPAL = 1;
1578	     } else if((!xf86NameCmp(strptr,"PALN")) ||
1579		       (!xf86NameCmp(strptr,"PAL-N"))) {
1580		pSiS->OptTVStand = 1;
1581		pSiS->NonDefaultPAL = 0;
1582	     } else if((!xf86NameCmp(strptr,"NTSCJ")) ||
1583		       (!xf86NameCmp(strptr,"NTSC-J"))) {
1584		pSiS->OptTVStand = 0;
1585		pSiS->NonDefaultNTSC = 1;
1586	     } else if(!xf86NameCmp(strptr,"NTSC"))
1587		pSiS->OptTVStand = 0;
1588	     else {
1589		SiS_PrintBadOpt(pScrn, strptr, OPTION_TVSTANDARD);
1590		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1591		    "%s \"PAL\", \"PALM\", \"PALN\", \"NTSC\", \"NTSCJ\"\n", validparm);
1592	     }
1593
1594	     if(pSiS->OptTVStand != -1) {
1595		static const char *tvstdstr = "TV standard shall be %s\n";
1596		if(pSiS->Chipset == PCI_CHIP_SIS6326) {
1597		   pSiS->NonDefaultPAL = -1;
1598		   pSiS->NonDefaultNTSC = -1;
1599		   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, tvstdstr,
1600			pSiS->OptTVStand ? "PAL" : "NTSC");
1601		} else {
1602		   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, tvstdstr,
1603		       (pSiS->OptTVStand ?
1604			   ( (pSiS->NonDefaultPAL == -1) ? "PAL" :
1605			      ((pSiS->NonDefaultPAL) ? "PALM" : "PALN") ) :
1606				(pSiS->NonDefaultNTSC == -1) ? "NTSC" : "NTSCJ"));
1607		}
1608	     }
1609	  }
1610       }
1611
1612       /* CHTVType  (315/330/later series + Chrontel only)
1613	* Used for telling the driver if the TV output shall
1614	* be 525i YPbPr or SCART.
1615	*/
1616       if(pSiS->VGAEngine == SIS_315_VGA) {
1617	  strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CHTVTYPE);
1618	  if(strptr != NULL) {
1619	     if(!xf86NameCmp(strptr,"SCART"))
1620		pSiS->chtvtype = 1;
1621	     else if(!xf86NameCmp(strptr,"YPBPR525I"))
1622		pSiS->chtvtype = 0;
1623	     else {
1624		SiS_PrintBadOpt(pScrn, strptr, OPTION_CHTVTYPE);
1625		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1626		  "%s \"SCART\" or \"YPBPR525I\"\n", validparm);
1627	     }
1628	     if(pSiS->chtvtype != -1)
1629		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1630		  "Chrontel: TV type shall be %s\n", strptr);
1631	  }
1632       }
1633
1634       /* CHTVOverscan (300/315/330 series and later only)
1635	* CHTVSuperOverscan (300/315/330 series and later only)
1636	* These options are for overriding the BIOS option for
1637	* TV Overscan. Some BIOSes don't even have such an option.
1638	* SuperOverscan is only supported with PAL.
1639	* Both options are only effective on machines with a
1640	* CHRONTEL TV encoder. SuperOverscan is only available
1641	* on the 700x.
1642	*/
1643       if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
1644	  if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVOVERSCAN, &val)) {
1645	     pSiS->OptTVOver = val ? 1 : 0;
1646	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1647	         "Chrontel: TV overscan shall be %s\n",
1648	         val ? enabledstr : disabledstr);
1649	  }
1650	  if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVSOVERSCAN, &pSiS->OptTVSOver)) {
1651	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1652	         "Chrontel: TV super overscan shall be %s\n",
1653	         pSiS->OptTVSOver ? enabledstr : disabledstr);
1654	  }
1655       }
1656
1657       /* Various parameters for TV output via SiS bridge, Chrontel or SiS6326
1658        */
1659       if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
1660	  int tmp = 0;
1661	  xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHCVBS,
1662				&pSiS->chtvlumabandwidthcvbs);
1663	  xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHSVIDEO,
1664				&pSiS->chtvlumabandwidthsvideo);
1665	  xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMAFLICKERFILTER,
1666				&pSiS->chtvlumaflickerfilter);
1667	  xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMABANDWIDTH,
1668				&pSiS->chtvchromabandwidth);
1669	  xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMAFLICKERFILTER,
1670				&pSiS->chtvchromaflickerfilter);
1671	  xf86GetOptValBool(pSiS->Options, OPTION_CHTVCVBSCOLOR,
1672				&pSiS->chtvcvbscolor);
1673	  xf86GetOptValInteger(pSiS->Options, OPTION_CHTVTEXTENHANCE,
1674				&pSiS->chtvtextenhance);
1675	  xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCONTRAST,
1676				&pSiS->chtvcontrast);
1677	  xf86GetOptValInteger(pSiS->Options, OPTION_SISTVEDGEENHANCE,
1678				&pSiS->sistvedgeenhance);
1679	  xf86GetOptValInteger(pSiS->Options, OPTION_SISTVSATURATION,
1680				&pSiS->sistvsaturation);
1681	  xf86GetOptValInteger(pSiS->Options, OPTION_SISTVLUMAFILTER,
1682				&pSiS->sistvyfilter);
1683	  if((pSiS->sistvyfilter < 0) || (pSiS->sistvyfilter > 8)) {
1684	     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1685		"Illegal Y Filter number; valid is 0 (off), 1 (default), 2-8 (filter number 1-7)\n");
1686	     pSiS->sistvyfilter = 1;
1687	  }
1688	  xf86GetOptValBool(pSiS->Options, OPTION_SISTVCHROMAFILTER,
1689				&pSiS->sistvcfilter);
1690	  xf86GetOptValInteger(pSiS->Options, OPTION_SISTVCOLCALIBCOARSE,
1691				&pSiS->sistvcolcalibc);
1692	  xf86GetOptValInteger(pSiS->Options, OPTION_SISTVCOLCALIBFINE,
1693				&pSiS->sistvcolcalibf);
1694	  if((pSiS->sistvcolcalibf > 127) || (pSiS->sistvcolcalibf < -128) ||
1695	     (pSiS->sistvcolcalibc > 120) || (pSiS->sistvcolcalibc < -120)) {
1696	     pSiS->sistvcolcalibf = pSiS->sistvcolcalibc = 0;
1697	     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1698	     	"Illegal Color Calibration. Range is -128 to 127 (fine), -120 to 120 (coarse)\n");
1699	  }
1700	  xf86GetOptValInteger(pSiS->Options, OPTION_TVXPOSOFFSET,
1701				&pSiS->tvxpos);
1702	  xf86GetOptValInteger(pSiS->Options, OPTION_TVYPOSOFFSET,
1703				&pSiS->tvypos);
1704	  if(pSiS->tvxpos > 32)  { pSiS->tvxpos = 32;  tmp = 1; }
1705	  if(pSiS->tvxpos < -32) { pSiS->tvxpos = -32; tmp = 1; }
1706	  if(pSiS->tvypos > 32)  { pSiS->tvypos = 32;  tmp = 1; }
1707	  if(pSiS->tvypos < -32) { pSiS->tvypos = -32;  tmp = 1; }
1708	  if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1709		      "Illegal TV x or y offset. Range is from -32 to 32\n");
1710	  tmp = 0;
1711	  xf86GetOptValInteger(pSiS->Options, OPTION_TVXSCALE,
1712				&pSiS->tvxscale);
1713	  xf86GetOptValInteger(pSiS->Options, OPTION_TVYSCALE,
1714				&pSiS->tvyscale);
1715	  if(pSiS->tvxscale > 16)  { pSiS->tvxscale = 16;  tmp = 1; }
1716	  if(pSiS->tvxscale < -16) { pSiS->tvxscale = -16; tmp = 1; }
1717	  if(pSiS->tvyscale > 3)  { pSiS->tvyscale = 3;  tmp = 1; }
1718	  if(pSiS->tvyscale < -4) { pSiS->tvyscale = -4; tmp = 1; }
1719	  if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1720		      "Illegal TV x or y scaling parameter. Range is from -16 to 16 (X), -4 to 3 (Y)\n");
1721       }
1722
1723       if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
1724	  int tmp = 0;
1725	  strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SIS6326FORCETVPPLUG);
1726	  if(strptr) {
1727	     if(!xf86NameCmp(strptr,"COMPOSITE"))
1728		pSiS->sis6326tvplug = 1;
1729	     else if(!xf86NameCmp(strptr,"SVIDEO"))
1730		pSiS->sis6326tvplug = 0;
1731	     else {
1732		SiS_PrintBadOpt(pScrn, strptr, OPTION_SIS6326FORCETVPPLUG);
1733		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1734		   "%s \"COMPOSITE\" or \"SVIDEO\"\n", validparm);
1735	     }
1736	  }
1737	  xf86GetOptValBool(pSiS->Options, OPTION_SIS6326ENABLEYFILTER,
1738				&pSiS->sis6326enableyfilter);
1739	  xf86GetOptValBool(pSiS->Options, OPTION_SIS6326YFILTERSTRONG,
1740				&pSiS->sis6326yfilterstrong);
1741	  xf86GetOptValInteger(pSiS->Options, OPTION_TVXPOSOFFSET,
1742				&pSiS->tvxpos);
1743	  xf86GetOptValInteger(pSiS->Options, OPTION_TVYPOSOFFSET,
1744				&pSiS->tvypos);
1745	  if(pSiS->tvxpos > 16)  { pSiS->tvxpos = 16;  tmp = 1; }
1746	  if(pSiS->tvxpos < -16) { pSiS->tvxpos = -16; tmp = 1; }
1747	  if(pSiS->tvypos > 16)  { pSiS->tvypos = 16;  tmp = 1; }
1748	  if(pSiS->tvypos < -16) { pSiS->tvypos = -16;  tmp = 1; }
1749	  if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1750		      "Illegal TV x or y offset. Range is from -16 to 16\n");
1751          xf86GetOptValInteger(pSiS->Options, OPTION_SIS6326FSCADJUST,
1752				&pSiS->sis6326fscadjust);
1753	  if(pSiS->sis6326fscadjust) {
1754	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1755		"Adjusting the default FSC by %d\n",
1756		pSiS->sis6326fscadjust);
1757	  }
1758       }
1759
1760       if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA) ||
1761	  ((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV))) {
1762	  Bool Is6326 = FALSE;
1763	  strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SISTVANTIFLICKER);
1764	  if(!strptr) {
1765	     strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SIS6326ANTIFLICKER);
1766	     Is6326 = TRUE;
1767	  }
1768	  if(strptr) {
1769	     if(!xf86NameCmp(strptr,"OFF"))
1770		pSiS->sistvantiflicker = 0;
1771	     else if(!xf86NameCmp(strptr,"LOW"))
1772		pSiS->sistvantiflicker = 1;
1773	     else if(!xf86NameCmp(strptr,"MED"))
1774		pSiS->sistvantiflicker = 2;
1775	     else if(!xf86NameCmp(strptr,"HIGH"))
1776		pSiS->sistvantiflicker = 3;
1777	     else if(!xf86NameCmp(strptr,"ADAPTIVE"))
1778		pSiS->sistvantiflicker = 4;
1779	     else {
1780		pSiS->sistvantiflicker = -1;
1781		SiS_PrintBadOpt(pScrn, strptr, Is6326 ? OPTION_SIS6326FORCETVPPLUG : OPTION_SISTVANTIFLICKER);
1782		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1783		    "%s \"OFF\", \"LOW\", \"MED\", \"HIGH\" or \"ADAPTIVE\"\n", validparm);
1784	     }
1785	  }
1786       }
1787
1788       /* CRT2Gamma - enable/disable/set gamma correction for CRT2
1789	* Since 2004/11/26, this option is a boolean and string option
1790	* simulaniously. "TRUE" (or other valid bool values) have the
1791	* same effect as before: The driver uses the (global) Gamma
1792	* for both CRT1 and CRT2. Otherwise, this option takes one or
1793	* three floats between 0.1 and 10.0 which define a separate
1794	* gamma correction for CRT2. (SiS video bridges only.)
1795	*/
1796       if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
1797	  if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CRT2GAMMA))) {
1798	     if(SiS_StrIsBoolOn(strptr)) {
1799		pSiS->CRT2gamma = TRUE;
1800		pSiS->CRT2SepGamma = FALSE;
1801	     } else if(SiS_StrIsBoolOff(strptr)) {
1802		pSiS->CRT2gamma = pSiS->CRT2SepGamma = FALSE;
1803	     } else {
1804		if(SiS_EvalOneOrThreeFloats(pScrn, OPTION_CRT2GAMMA, gammaopt, strptr,
1805				&pSiS->GammaR2i, &pSiS->GammaG2i, &pSiS->GammaB2i)) {
1806		   pSiS->GammaR2 = (float)pSiS->GammaR2i / 1000.0;
1807		   pSiS->GammaG2 = (float)pSiS->GammaG2i / 1000.0;
1808		   pSiS->GammaB2 = (float)pSiS->GammaB2i / 1000.0;
1809		   pSiS->CRT2gamma = TRUE;
1810		   if(!IsDHM) pSiS->CRT2SepGamma = TRUE;
1811		   else {
1812#ifdef SISDUALHEAD
1813		      pSiS->CRT2SepGamma = FALSE;
1814		      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1815				"CRT2Gamma values overrule default and Monitor Gamma\n");
1816		      if(pScrn->monitor) {
1817			 pScrn->monitor->gamma.red = pSiS->GammaR2;
1818			 pScrn->monitor->gamma.green = pSiS->GammaG2;
1819			 pScrn->monitor->gamma.blue = pSiS->GammaB2;
1820		      }
1821#endif
1822		   }
1823		}
1824	     }
1825	  }
1826       }
1827
1828       /* Default adaptor: Overlay (default) or blitter */
1829       if(pSiS->VGAEngine == SIS_315_VGA) {
1830	  if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_XVDEFAULTADAPTOR))) {
1831	     if(!xf86NameCmp(strptr, "OVERLAY")) {
1832		pSiS->XvDefAdaptorBlit = FALSE;
1833	     } else if(!xf86NameCmp(strptr, "BLITTER")) {
1834		pSiS->XvDefAdaptorBlit = TRUE;
1835	     } else {
1836		SiS_PrintBadOpt(pScrn, strptr, OPTION_XVDEFAULTADAPTOR);
1837		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1838			"%s \"OVERLAY\" or \"BLITTER\"\n", validparm);
1839	     }
1840	  }
1841       }
1842
1843       if(xf86GetOptValBool(pSiS->Options, OPTION_XVMEMCPY, &val)) {
1844	  pSiS->XvUseMemcpy = val ? TRUE : FALSE;
1845	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv will %suse memcpy()\n",
1846		val ? "" : "not ");
1847       }
1848
1849#if defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
1850       if(xf86GetOptValBool(pSiS->Options, OPTION_XVBENCHCPY, &val)) {
1851	  pSiS->BenchMemCpy = val ? TRUE : FALSE;
1852	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1853		"Will %sbenchmark methods for system RAM to video RAM transfers\n",
1854		val ? "" : "not ");
1855       }
1856
1857#ifndef SISCHECKOSSSE
1858       if(xf86GetOptValBool(pSiS->Options, OPTION_XVSSECOPY, &val)) {
1859	  pSiS->XvSSEMemcpy = val ? TRUE : FALSE;
1860	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1861		"Will %s use SSE CPU instructions\n",
1862		val ? "eventually" : "not");
1863       }
1864#endif
1865#endif /* __i386__ || __AMD64__ || __amd64__ */
1866
1867#ifdef SIS_CP
1868       SIS_CP_OPT_DOOPT
1869#endif
1870
1871    }  /* DualHead */
1872
1873    /* CRT1Gamma - enable/disable gamma correction for CRT1
1874     */
1875    if(xf86GetOptValBool(pSiS->Options, OPTION_CRT1GAMMA, &val)) {
1876       pSiS->CRT1gamma = val;
1877       pSiS->CRT1gammaGiven = TRUE;
1878    }
1879
1880    /* ForceCRT1Aspect, ForceCRT2Aspect */
1881    /* Make driver believe that a connected CRT/VGA device is 4:3 ("normal")
1882     * or 16:9 ("wide"). Note: This affects only for real VGA (analog)
1883     * output devices, not TV or DVI/LCD.
1884     */
1885    if(pSiS->VGAEngine == SIS_315_VGA) {
1886       strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_FORCE1ASPECT);
1887       if(strptr != NULL) {
1888	  if(!xf86NameCmp(strptr,"WIDE")) {
1889	     pSiS->SiS_Pr->SiS_UseWide = 1;
1890	  } else if(!xf86NameCmp(strptr,"NORMAL")) {
1891	     pSiS->SiS_Pr->SiS_UseWide = 0;
1892	  } else {
1893	     SiS_PrintBadOpt(pScrn, strptr, OPTION_FORCE1ASPECT);
1894	     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s:\n", validparm);
1895	     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t\"NORMAL\" or \"WIDE\"\n");
1896          }
1897	  if(pSiS->SiS_Pr->SiS_UseWide != -1) {
1898	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1899		"CRT1 (VGA) aspect ratio will be assumed %s\n",
1900		pSiS->SiS_Pr->SiS_UseWide ? "wide" : "normal");
1901	  }
1902       }
1903       if(pSiS->SiS_Pr->SiS_UseWideCRT2 != -1) {
1904	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1905		"CRT2 (VGA) aspect ratio will be assumed %s\n",
1906		pSiS->SiS_Pr->SiS_UseWideCRT2 ? "wide" : "normal");
1907       }
1908    }
1909
1910    /* VESA - DEPRECATED
1911     * This option is for forcing the driver to use
1912     * the VESA BIOS extension for mode switching.
1913     */
1914    if(xf86GetOptValBool(pSiS->Options, OPTION_VESA, &val)) {
1915       if(IsDHM) {
1916	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING, baddhm,
1917	     pSiS->Options[SiS_FIFT(pSiS->Options, OPTION_VESA)].name);
1918       } else {
1919	  pSiS->VESA = val ? 1 : 0;
1920	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1921		"VESA: VESA usage shall be %s\n",
1922		val ? enabledstr : disabledstr);
1923          xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1924		"*** Option \"VESA\" is deprecated. *** \n");
1925	  if(pSiS->VESA) pSiS->ForceCRT1Type = CRT1_VGA;
1926       }
1927    }
1928
1929    if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
1930       /* InternalModes (300/315/330 series only)
1931	* The default behavior is to replace X's default modes with
1932	* a mode list generated out of the known and supported modes. Use
1933	* this option to disable this. NOT RECOMMENDED.
1934	*/
1935       if(xf86GetOptValBool(pSiS->Options, OPTION_INTERNALMODES, &val)) {
1936	  pSiS->noInternalModes = val ? FALSE : TRUE;
1937	  if(pSiS->noInternalModes) {
1938	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Usage of built-in modes is %s\n", disabledstr);
1939	  }
1940       }
1941
1942    }
1943
1944    /* ShadowFB */
1945    from = X_DEFAULT;
1946    if(xf86GetOptValBool(pSiS->Options, OPTION_SHADOW_FB, &pSiS->ShadowFB)) {
1947#ifdef SISMERGED
1948       if(pSiS->MergedFB) {
1949	  pSiS->ShadowFB = FALSE;
1950	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1951	      "Shadow Framebuffer not supported in MergedFB mode\n");
1952       } else
1953#endif
1954	  from = X_CONFIG;
1955    }
1956    if(pSiS->ShadowFB) {
1957	pSiS->NoAccel = TRUE;
1958#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
1959	pSiS->NoXvideo = TRUE;
1960	xf86DrvMsg(pScrn->scrnIndex, from,
1961	   "Using \"Shadow Framebuffer\" - 2D acceleration and Xv disabled\n");
1962#else
1963	xf86DrvMsg(pScrn->scrnIndex, from,
1964	   "Using \"Shadow Framebuffer\" - 2D acceleration disabled\n");
1965#endif
1966    }
1967
1968    /* Rotate */
1969    if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_ROTATE))) {
1970#ifdef SISMERGED
1971       if(pSiS->MergedFB) {
1972	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1973	      "Screen rotation not supported in MergedFB mode\n");
1974       } else
1975#endif
1976       if(IsDHM) {
1977	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING, baddhm,
1978	     pSiS->Options[SiS_FIFT(pSiS->Options, OPTION_ROTATE)].name);
1979       } else if(!xf86NameCmp(strptr, "CW")) {
1980	  pSiS->Rotate = 1;
1981       } else if(!xf86NameCmp(strptr, "CCW")) {
1982	  pSiS->Rotate = -1;
1983       } else {
1984	  SiS_PrintBadOpt(pScrn, strptr, OPTION_ROTATE);
1985	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1986	      "%s \"CW\" or \"CCW\"\n", validparm);
1987       }
1988
1989       if(pSiS->Rotate) {
1990	  pSiS->ShadowFB = TRUE;
1991	  pSiS->NoAccel  = TRUE;
1992	  pSiS->HWCursor = FALSE;
1993	  pSiS->NoXvideo = TRUE;
1994	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1995	      "Rotating screen %sclockwise (2D acceleration and Xv disabled)\n",
1996	      (pSiS->Rotate == -1) ? "counter " : "");
1997       }
1998    }
1999
2000    /* Reflect */
2001    if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_REFLECT))) {
2002#ifdef SISMERGED
2003       if(pSiS->MergedFB) {
2004	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2005	      "Screen reflection not supported in MergedFB mode\n");
2006       } else
2007#endif
2008       if(IsDHM) {
2009	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING, baddhm,
2010	     pSiS->Options[SiS_FIFT(pSiS->Options, OPTION_REFLECT)].name);
2011       } else if(pSiS->Rotate) {
2012	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2013	  	"Screen rotation and reflection are mutually exclusive\n");
2014       } else if(!xf86NameCmp(strptr, "X")) {
2015	  pSiS->Reflect = 1;
2016       } else if(!xf86NameCmp(strptr, "Y")) {
2017	  pSiS->Reflect = 2;
2018       } else if((!xf86NameCmp(strptr, "XY")) ||
2019		 (!xf86NameCmp(strptr, "YX"))) {
2020	  pSiS->Reflect = 3;
2021       } else {
2022	  SiS_PrintBadOpt(pScrn, strptr, OPTION_REFLECT);
2023	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2024	      "%s \"X\", \"Y\" or \"XY\"\n", validparm);
2025       }
2026
2027       if(pSiS->Reflect) {
2028	  pSiS->ShadowFB = TRUE;
2029	  pSiS->NoAccel  = TRUE;
2030	  pSiS->HWCursor = FALSE;
2031	  pSiS->NoXvideo = TRUE;
2032	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2033	      "Reflecting screen (2D acceleration and Xv disabled)\n");
2034       }
2035    }
2036
2037#ifdef SISDRI
2038    /* DRI */
2039    from = X_DEFAULT;
2040    if(xf86GetOptValBool(pSiS->Options, OPTION_DRI, &pSiS->loadDRI)) {
2041       from = X_CONFIG;
2042    }
2043    xf86DrvMsg(pScrn->scrnIndex, from, "DRI %s\n",
2044		pSiS->loadDRI ? enabledstr : disabledstr);
2045
2046    /* AGPSize = GARTSize */
2047    if(xf86GetOptValInteger(pSiS->Options, OPTION_AGP_SIZE, &ival)) {
2048       if((ival >= 8) && (ival <= 512)) {
2049	  pSiS->agpWantedPages = (ival * 1024 * 1024) / AGP_PAGE_SIZE;
2050       } else {
2051	  SiS_PrintIlRange(pScrn, OPTION_AGP_SIZE, 8, 512, 0);
2052       }
2053    }
2054#endif
2055
2056    /* XVideo
2057     * Set enables/disables Xv hardware video acceleration
2058     */
2059#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
2060    if((!pSiS->NoAccel) && (!pSiS->NoXvideo)) {
2061#else
2062    if(!pSiS->NoXvideo) {
2063#endif
2064       if(!xf86ReturnOptValBool(pSiS->Options, OPTION_XVIDEO, TRUE)) {
2065	  pSiS->NoXvideo = TRUE;
2066	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XVideo extension (Xv) disabled\n");
2067       }
2068
2069       if(!pSiS->NoXvideo) {
2070
2071	  if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
2072	     /* XvOnCRT2
2073	      * On chipsets with only one overlay (315, 650, 740, 330), the user can
2074	      * choose to display the overlay on CRT1 or CRT2. By setting this
2075	      * option to TRUE, the overlay will be displayed on CRT2. The
2076	      * default is: CRT1 if only CRT1 available, CRT2 if only CRT2
2077	      * available, and CRT1 if both is available and detected.
2078	      * Since implementation of the XV_SWITCHCRT Xv property this only
2079	      * selects the default CRT.
2080	      */
2081	     if(xf86GetOptValBool(pSiS->Options, OPTION_XVONCRT2, &val)) {
2082	        pSiS->XvOnCRT2 = val ? TRUE : FALSE;
2083	     }
2084	  }
2085
2086	  if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
2087	     /* NoYV12 (for 5597/5598, 6326 and 530/620 only)
2088	      * YV12 has problems with videos larger than 384x288. So
2089	      * allow the user to disable YV12 support to force the
2090	      * application to use YUV2 instead.
2091	      */
2092	     if(xf86GetOptValBool(pSiS->Options, OPTION_YV12, &val)) {
2093		pSiS->NoYV12 = val ? 0 : 1;
2094		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2095			"Xv YV12/I420 support is %s\n",
2096			pSiS->NoYV12 ? disabledstr : enabledstr);
2097	     }
2098	  }
2099
2100	  /* Some Xv properties' defaults can be set by options */
2101	  if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFCONTRAST, &ival)) {
2102	     if((ival >= 0) && (ival <= 7)) pSiS->XvDefCon = ival;
2103	     else SiS_PrintIlRange(pScrn, OPTION_XVDEFCONTRAST, 0, 7, 0);
2104	  }
2105	  if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFBRIGHTNESS, &ival)) {
2106	     if((ival >= -128) && (ival <= 127)) pSiS->XvDefBri = ival;
2107	     else SiS_PrintIlRange(pScrn, OPTION_XVDEFBRIGHTNESS, -128, 127, 0);
2108	  }
2109	  if(pSiS->VGAEngine == SIS_315_VGA) {
2110	     if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFHUE, &ival)) {
2111		if((ival >= -8) && (ival <= 7)) pSiS->XvDefHue = ival;
2112		else SiS_PrintIlRange(pScrn, OPTION_XVDEFHUE, -8, 7, 0);
2113	     }
2114	     if(xf86GetOptValInteger(pSiS->Options, OPTION_XVDEFSATURATION, &ival)) {
2115		if((ival >= -7) && (ival <= 7)) pSiS->XvDefSat = ival;
2116		else SiS_PrintIlRange(pScrn, OPTION_XVDEFSATURATION, -7, 7, 0);
2117	     }
2118	  }
2119	  if(xf86GetOptValBool(pSiS->Options, OPTION_XVDEFDISABLEGFX, &val)) {
2120	     if(val) pSiS->XvDefDisableGfx = TRUE;
2121	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2122		"Graphics display will be %s during Xv usage\n",
2123		val ? disabledstr : enabledstr);
2124	  }
2125	  if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
2126	     if(xf86GetOptValBool(pSiS->Options, OPTION_XVDEFDISABLEGFXLR, &val)) {
2127		if(val) pSiS->XvDefDisableGfxLR = TRUE;
2128		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2129		   "Graphics display left/right of overlay will be %s during Xv usage\n",
2130		   val ? disabledstr : enabledstr);
2131	     }
2132	     if(xf86GetOptValBool(pSiS->Options, OPTION_XVDISABLECOLORKEY, &val)) {
2133		if(val) pSiS->XvDisableColorKey = TRUE;
2134		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2135		   "Xv Color key is %s\n",
2136		   val ? disabledstr : enabledstr);
2137	     }
2138	     if(xf86GetOptValBool(pSiS->Options, OPTION_XVUSECHROMAKEY, &val)) {
2139		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2140		   "Xv Chroma-keying is %s\n",
2141		   val ? enabledstr : disabledstr);
2142		if(val) pSiS->XvUseChromaKey = TRUE;
2143             }
2144	     if(xf86GetOptValBool(pSiS->Options, OPTION_XVINSIDECHROMAKEY, &val)) {
2145		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2146		   "Xv: Video is transparent if %s chroma key range\n",
2147		   val ? "inside" : "outside");
2148		if(val) pSiS->XvInsideChromaKey = TRUE;
2149             }
2150	     if(pSiS->VGAEngine == SIS_300_VGA) {
2151		if(xf86GetOptValBool(pSiS->Options, OPTION_XVYUVCHROMAKEY, &val)) {
2152		   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2153		      "Xv: Chroma key is in %s format\n",
2154		      val ? "YUV" : "RGB");
2155		   if(val) pSiS->XvYUVChromaKey = TRUE;
2156		}
2157             } else {
2158                if(xf86GetOptValBool(pSiS->Options, OPTION_XVYUVCHROMAKEY, &val)) {
2159		   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
2160		      "Xv: Chroma key is of same format as video source\n");
2161		}
2162	     }
2163	     if(xf86GetOptValInteger(pSiS->Options, OPTION_XVCHROMAMIN, &ival)) {
2164		if((ival >= 0) && (ival <= 0xffffff)) pSiS->XvChromaMin = ival;
2165		else SiS_PrintIlRange(pScrn, OPTION_XVCHROMAMIN, 0, 0xffffff, 1);
2166	     }
2167	     if(xf86GetOptValInteger(pSiS->Options, OPTION_XVCHROMAMAX, &ival)) {
2168		if((ival >= 0) && (ival <= 0xffffff)) pSiS->XvChromaMax = ival;
2169		else SiS_PrintIlRange(pScrn, OPTION_XVCHROMAMAX, 0, 0xffffff, 1);
2170             }
2171	  }
2172
2173	  if(pSiS->VGAEngine == SIS_315_VGA) {
2174	     /* XvGamma - enable/disable gamma correction for Xv
2175	      * Supported for CRT1 only
2176	      */
2177	     if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_XVGAMMA))) {
2178		if(SiS_StrIsBoolOn(strptr)) {
2179		   pSiS->XvGamma = pSiS->XvGammaGiven = TRUE;
2180		} else if(SiS_StrIsBoolOff(strptr)) {
2181		   pSiS->XvGamma = FALSE;
2182		   pSiS->XvGammaGiven = TRUE;
2183		} else {
2184		   if(SiS_EvalOneOrThreeFloats(pScrn, OPTION_XVGAMMA, gammaopt, strptr,
2185				&pSiS->XvGammaRed, &pSiS->XvGammaGreen, &pSiS->XvGammaBlue)) {
2186		      pSiS->XvGamma = pSiS->XvGammaGiven = TRUE;
2187		      pSiS->XvGammaRedDef = pSiS->XvGammaRed;
2188		      pSiS->XvGammaGreenDef = pSiS->XvGammaGreen;
2189		      pSiS->XvGammaBlue = pSiS->XvGammaBlue;
2190		   }
2191		}
2192	     }
2193	  }
2194       }
2195    }
2196
2197    if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
2198       Bool GotNewBri = FALSE, GotOldBri = FALSE, GotCon = FALSE;
2199       if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_NEWSTOREDCON))) {
2200	  SiS_EvalOneOrThreeFloats2(pScrn, OPTION_NEWSTOREDCON, newbriopt, strptr,
2201		&pSiS->NewGammaConR, &pSiS->NewGammaConG, &pSiS->NewGammaConB);
2202	  GotCon = TRUE;
2203       }
2204       if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_NEWSTOREDBRI))) {
2205	  SiS_EvalOneOrThreeFloats2(pScrn, OPTION_NEWSTOREDBRI, newbriopt, strptr,
2206		&pSiS->NewGammaBriR, &pSiS->NewGammaBriG, &pSiS->NewGammaBriB);
2207	  GotNewBri = TRUE;
2208       }
2209       if(!GotCon && !GotNewBri) {
2210          if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_STOREDBRI))) {
2211	     SiS_EvalOneOrThreeFloats(pScrn, OPTION_STOREDBRI, briopt, strptr,
2212		   &pSiS->GammaBriR, &pSiS->GammaBriG, &pSiS->GammaBriB);
2213	     GotOldBri = TRUE;
2214	     pSiS->SiS_SD3_Flags |= SiS_SD3_OLDGAMMAINUSE;
2215	  }
2216       }
2217
2218       if((!IsDHM) || (IsDHM && !IsSecondHead)) {
2219          Bool GotCon2 = FALSE, GotNewBri2 = FALSE;
2220          if(!GotOldBri) {
2221             if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_NEWSTOREDCON2))) {
2222	        SiS_EvalOneOrThreeFloats2(pScrn, OPTION_NEWSTOREDCON2, newbriopt, strptr,
2223		      &pSiS->NewGammaConR2, &pSiS->NewGammaConG2, &pSiS->NewGammaConB2);
2224	        GotCon2 = TRUE;
2225             }
2226             if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_NEWSTOREDBRI2))) {
2227	        if(SiS_EvalOneOrThreeFloats2(pScrn, OPTION_NEWSTOREDBRI2, newbriopt, strptr,
2228				&pSiS->NewGammaBriR2, &pSiS->NewGammaBriG2, &pSiS->NewGammaBriB2)) {
2229		   if(IsDHM) {
2230#ifdef SISDUALHEAD
2231		      if(GotNewBri) SiS_PrintOverruleDHM(pScrn, OPTION_NEWSTOREDBRI2, OPTION_NEWSTOREDBRI);
2232		      pSiS->NewGammaBriR = pSiS->NewGammaBriR2;
2233		      pSiS->NewGammaBriG = pSiS->NewGammaBriG2;
2234		      pSiS->NewGammaBriB = pSiS->NewGammaBriB2;
2235#endif
2236	           } else pSiS->CRT2SepGamma = TRUE;
2237	        }
2238	        GotNewBri2 = TRUE;
2239	     }
2240          }
2241          if(!GotCon2 && !GotNewBri2 && !GotNewBri && !GotCon) {
2242	     if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_STOREDBRI2))) {
2243	        pSiS->SiS_SD3_Flags |= SiS_SD3_OLDGAMMAINUSE;
2244	        if(SiS_EvalOneOrThreeFloats(pScrn, OPTION_STOREDBRI2, briopt, strptr,
2245		    &pSiS->GammaBriR2, &pSiS->GammaBriG2, &pSiS->GammaBriB2)) {
2246	           if(IsDHM) {
2247#ifdef SISDUALHEAD
2248		      if(GotOldBri) SiS_PrintOverruleDHM(pScrn, OPTION_STOREDBRI2, OPTION_STOREDBRI);
2249		      pSiS->GammaBriR = pSiS->GammaBriR2;
2250		      pSiS->GammaBriG = pSiS->GammaBriG2;
2251		      pSiS->GammaBriB = pSiS->GammaBriB2;
2252#endif
2253	           } else pSiS->CRT2SepGamma = TRUE;
2254	        }
2255	     }
2256	  }
2257       }
2258    }
2259
2260    if(pSiS->SiS_SD3_Flags & SiS_SD3_CRT1SATGAIN) {
2261       if(xf86GetOptValInteger(pSiS->Options, OPTION_CRT1SATGAIN, &ival)) {
2262          if((ival >= 0) && (ival <= 7)) {
2263             pSiS->siscrt1satgain = ival;
2264             pSiS->crt1satgaingiven = TRUE;
2265          } else SiS_PrintIlRange(pScrn, OPTION_CRT1SATGAIN, 0, 7, 0);
2266       }
2267    }
2268
2269}
2270
2271const OptionInfoRec *
2272SISAvailableOptions(int chipid, int busid)
2273{
2274    return SISOptions;
2275}
2276