1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c,v 1.48 2004/01/23 22:29:06 twini Exp $ */
3 * Xv driver for SiS 300, 315 and 330 series.
5 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3) All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: "This product includes
17 * software developed by Thomas Winischhofer, Vienna, Austria."
18 * 4) The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Author: Thomas Winischhofer <thomas@winischhofer.net>
34 * Formerly based on a mostly non-working code fragment for the 630 by
35 * Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan which is
36 * Copyright (C) 2000 Silicon Integrated Systems Corp, Inc.
38 * Basic structure based on the mga Xv driver by Mark Vojkovich
39 * and i810 Xv driver by Jonathan Bian <jonathan.bian@intel.com>.
41 * All comments in this file are by Thomas Winischhofer.
43 * This supports the following chipsets:
44 * SiS300: No registers >0x65, two overlays (one used for CRT1, one for CRT2)
45 * SiS630/730: No registers >0x6b, two overlays (one used for CRT1, one for CRT2)
46 * SiS550: Full register range, two overlays (one used for CRT1, one for CRT2)
47 * SiS315: Full register range, one overlay (used for both CRT1 and CRT2 alt.)
48 * SiS650/740: Full register range, one overlay (used for both CRT1 and CRT2 alt.)
49 * SiSM650/651: Full register range, two overlays (one used for CRT1, one for CRT2)
50 * SiS330: Full register range, one overlay (used for both CRT1 and CRT2 alt.)
51 * SiS661/741/760: Full register range, two overlays (one used for CRT1, one for CRT2)
53 * Help for reading the code:
54 * 315/550/650/740/M650/651/330/661/741/760 = SIS_315_VGA
55 * 300/630/730 = SIS_300_VGA
56 * For chipsets with 2 overlays, hasTwoOverlays will be true
58 * Notes on display modes:
61 * DISPMODE is either SINGLE1 or SINGLE2, hence you need to check dualHeadMode flag
62 * DISPMODE is _never_ MIRROR.
63 * a) Chipsets with 2 overlays:
64 * 315/330 series: Only half sized overlays available (width 960), 660: 1536
65 * Overlay 1 is used on CRT1, overlay 2 for CRT2.
66 * b) Chipsets with 1 overlay:
67 * Full size overlays available.
68 * Overlay is used for either CRT1 or CRT2
70 * a) Chipsets with 2 overlays:
71 * 315/330 series: Only half sized overlays available (width 960), 660: 1536
72 * DISPMODE is always MIRROR. Overlay 1 is used for CRT1, overlay 2 for CRT2.
73 * b) Chipsets with 1 overlay:
74 * Full size overlays available.
75 * DISPMODE is either SINGLE1 or SINGLE2. Overlay is used accordingly on either
76 * CRT1 or CRT2 (automatically, where it is located)
77 * -) mirror mode (without dualhead or mergedfb)
78 * a) Chipsets with 2 overlays:
79 * 315/330 series: Only half sized overlays available (width 960), 660: 1536
80 * DISPMODE is MIRROR. Overlay 1 is used for CRT1, overlay 2 for CRT2.
81 * b) Chipsets with 1 overlay:
82 * Full size overlays available.
83 * DISPMODE is either SINGLE1 or SINGLE2. Overlay is used depending on
88 #include "xf86_OSproc.h"
89 #include "xf86Resources.h"
90 #include "xf86_ansic.h"
92 #include "xf86PciInfo.h"
94 #include "xf86fbman.h"
95 #include "regionstr.h"
101 #include "xaalocal.h"
102 #include "dixstruct.h"
105 #include "sis_regs.h"
107 static XF86VideoAdaptorPtr
SISSetupImageVideo(ScreenPtr
);
108 static void SISStopVideo(ScrnInfoPtr
, pointer
, Bool
);
109 static int SISSetPortAttribute(ScrnInfoPtr
, Atom
, INT32
, pointer
);
110 static int SISGetPortAttribute(ScrnInfoPtr
, Atom
,INT32
*, pointer
);
111 static void SISQueryBestSize(ScrnInfoPtr
, Bool
, short, short, short,
112 short, unsigned int *,unsigned int *, pointer
);
113 static int SISPutImage( ScrnInfoPtr
,
114 short, short, short, short, short, short, short, short,
115 int, unsigned char*, short, short, Bool
, RegionPtr
, pointer
);
116 static int SISQueryImageAttributes(ScrnInfoPtr
,
117 int, unsigned short *, unsigned short *, int *, int *);
118 static void SISVideoTimerCallback(ScrnInfoPtr pScrn
, Time now
);
119 static void SISInitOffscreenImages(ScreenPtr pScrn
);
120 extern BOOLEAN
SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn
);
122 #define OFF_DELAY 200 /* milliseconds */
123 #define FREE_DELAY 60000
125 #define OFF_TIMER 0x01
126 #define FREE_TIMER 0x02
127 #define CLIENT_VIDEO_ON 0x04
129 #define TIMER_MASK (OFF_TIMER | FREE_TIMER)
131 #define WATCHDOG_DELAY 500000 /* Watchdog counter for Vertical Restrace waiting */
133 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
135 #define IMAGE_MIN_WIDTH 32 /* Minimum and maximum source image sizes */
136 #define IMAGE_MIN_HEIGHT 24
137 #define IMAGE_MAX_WIDTH_300 720
138 #define IMAGE_MAX_HEIGHT_300 576
139 #define IMAGE_MAX_WIDTH_315 1920
140 #define IMAGE_MAX_HEIGHT_315 1080
142 #define OVERLAY_MIN_WIDTH 32 /* Minimum overlay sizes */
143 #define OVERLAY_MIN_HEIGHT 24
145 #define DISPMODE_SINGLE1 0x1 /* CRT1 only */
146 #define DISPMODE_SINGLE2 0x2 /* CRT2 only */
147 #define DISPMODE_MIRROR 0x4 /* CRT1 + CRT2 MIRROR (see note below) */
149 #define LINEBUFLIMIT1 384 /* Limits at which line buffers must be merged */
150 #define LINEBUFLIMIT2 720
151 #define LINEBUFLIMIT3 576
154 #define HEADOFFSET (pSiS->dhmOffset)
157 #define GET_PORT_PRIVATE(pScrn) \
158 (SISPortPrivPtr)((SISPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
161 * When using VESA on machines with an enabled video bridge, this means
162 * a real mirror. CRT1 and CRT2 have the exact same resolution and
163 * refresh rate. The same applies to modes which require the bridge to
164 * operate in slave mode.
165 * When not using VESA and the bridge is not in slave mode otherwise,
166 * CRT1 and CRT2 have the same resolution but possibly a different
170 /* client libraries expect an encoding */
171 static XF86VideoEncodingRec DummyEncoding
=
175 0, 0, /* Will be filled in */
179 #define NUM_FORMATS 3
181 static XF86VideoFormatRec SISFormats
[NUM_FORMATS
] =
188 static char sisxvcolorkey
[] = "XV_COLORKEY";
189 static char sisxvbrightness
[] = "XV_BRIGHTNESS";
190 static char sisxvcontrast
[] = "XV_CONTRAST";
191 static char sisxvsaturation
[] = "XV_SATURATION";
192 static char sisxvhue
[] = "XV_HUE";
193 static char sisxvautopaintcolorkey
[] = "XV_AUTOPAINT_COLORKEY";
194 static char sisxvsetdefaults
[] = "XV_SET_DEFAULTS";
195 static char sisxvswitchcrt
[] = "XV_SWITCHCRT";
196 static char sisxvtvxposition
[] = "XV_TVXPOSITION";
197 static char sisxvtvyposition
[] = "XV_TVYPOSITION";
198 static char sisxvgammared
[] = "XV_GAMMA_RED";
199 static char sisxvgammagreen
[] = "XV_GAMMA_GREEN";
200 static char sisxvgammablue
[] = "XV_GAMMA_BLUE";
201 static char sisxvdisablegfx
[] = "XV_DISABLE_GRAPHICS";
202 static char sisxvdisablegfxlr
[] = "XV_DISABLE_GRAPHICS_LR";
203 static char sisxvdisablecolorkey
[] = "XV_DISABLE_COLORKEY";
204 static char sisxvusechromakey
[] = "XV_USE_CHROMAKEY";
205 static char sisxvinsidechromakey
[] = "XV_INSIDE_CHROMAKEY";
206 static char sisxvyuvchromakey
[] = "XV_YUV_CHROMAKEY";
207 static char sisxvchromamin
[] = "XV_CHROMAMIN";
208 static char sisxvchromamax
[] = "XV_CHROMAMAX";
209 static char sisxvqueryvbflags
[] = "XV_QUERYVBFLAGS";
210 static char sisxvsdgetdriverversion
[] = "XV_SD_GETDRIVERVERSION";
211 static char sisxvsdgethardwareinfo
[] = "XV_SD_GETHARDWAREINFO";
212 static char sisxvsdgetbusid
[] = "XV_SD_GETBUSID";
213 static char sisxvsdqueryvbflagsversion
[] = "XV_SD_QUERYVBFLAGSVERSION";
214 static char sisxvsdgetsdflags
[] = "XV_SD_GETSDFLAGS";
215 static char sisxvsdunlocksisdirect
[] = "XV_SD_UNLOCKSISDIRECT";
216 static char sisxvsdsetvbflags
[] = "XV_SD_SETVBFLAGS";
217 static char sisxvsdquerydetecteddevices
[] = "XV_SD_QUERYDETECTEDDEVICES";
218 static char sisxvsdcrt1status
[] = "XV_SD_CRT1STATUS";
219 static char sisxvsdcheckmodeindexforcrt2
[] = "XV_SD_CHECKMODEINDEXFORCRT2";
220 static char sisxvsdresultcheckmodeindexforcrt2
[] = "XV_SD_RESULTCHECKMODEINDEXFORCRT2";
221 static char sisxvsdsisantiflicker
[] = "XV_SD_SISANTIFLICKER";
222 static char sisxvsdsissaturation
[] = "XV_SD_SISSATURATION";
223 static char sisxvsdsisedgeenhance
[] = "XV_SD_SISEDGEENHANCE";
224 static char sisxvsdsiscolcalibf
[] = "XV_SD_SISCOLCALIBF";
225 static char sisxvsdsiscolcalibc
[] = "XV_SD_SISCOLCALIBC";
226 static char sisxvsdsiscfilter
[] = "XV_SD_SISCFILTER";
227 static char sisxvsdsisyfilter
[] = "XV_SD_SISYFILTER";
228 static char sisxvsdchcontrast
[] = "XV_SD_CHCONTRAST";
229 static char sisxvsdchtextenhance
[] = "XV_SD_CHTEXTENHANCE";
230 static char sisxvsdchchromaflickerfilter
[] = "XV_SD_CHCHROMAFLICKERFILTER";
231 static char sisxvsdchlumaflickerfilter
[] = "XV_SD_CHLUMAFLICKERFILTER";
232 static char sisxvsdchcvbscolor
[] = "XV_SD_CHCVBSCOLOR";
233 static char sisxvsdchoverscan
[] = "XV_SD_CHOVERSCAN";
234 static char sisxvsdenablegamma
[] = "XV_SD_ENABLEGAMMA";
235 static char sisxvsdtvxscale
[] = "XV_SD_TVXSCALE";
236 static char sisxvsdtvyscale
[] = "XV_SD_TVYSCALE";
237 static char sisxvsdgetscreensize
[] = "XV_SD_GETSCREENSIZE";
238 static char sisxvsdstorebrir
[] = "XV_SD_STOREDGAMMABRIR";
239 static char sisxvsdstorebrig
[] = "XV_SD_STOREDGAMMABRIG";
240 static char sisxvsdstorebrib
[] = "XV_SD_STOREDGAMMABRIB";
241 static char sisxvsdstorepbrir
[] = "XV_SD_STOREDGAMMAPBRIR";
242 static char sisxvsdstorepbrig
[] = "XV_SD_STOREDGAMMAPBRIG";
243 static char sisxvsdstorepbrib
[] = "XV_SD_STOREDGAMMAPBRIB";
244 static char sisxvsdstorebrir2
[] = "XV_SD_STOREDGAMMABRIR2";
245 static char sisxvsdstorebrig2
[] = "XV_SD_STOREDGAMMABRIG2";
246 static char sisxvsdstorebrib2
[] = "XV_SD_STOREDGAMMABRIB2";
247 static char sisxvsdstorepbrir2
[] = "XV_SD_STOREDGAMMAPBRIR2";
248 static char sisxvsdstorepbrig2
[] = "XV_SD_STOREDGAMMAPBRIG2";
249 static char sisxvsdstorepbrib2
[] = "XV_SD_STOREDGAMMAPBRIB2";
250 static char sisxvsdhidehwcursor
[] = "XV_SD_HIDEHWCURSOR";
252 static char sisxvsetreg
[] = "XV_SD_SETREG";
256 #define NUM_ATTRIBUTES_300 56
258 #define NUM_ATTRIBUTES_315 63
260 #define NUM_ATTRIBUTES_315 62
264 static XF86AttributeRec SISAttributes_300
[NUM_ATTRIBUTES_300
] =
266 {XvSettable
| XvGettable
, 0, (1 << 24) - 1, sisxvcolorkey
},
267 {XvSettable
| XvGettable
, -128, 127, sisxvbrightness
},
268 {XvSettable
| XvGettable
, 0, 7, sisxvcontrast
},
269 {XvSettable
| XvGettable
, 0, 1, sisxvautopaintcolorkey
},
270 {XvSettable
, 0, 0, sisxvsetdefaults
},
271 {XvSettable
| XvGettable
, -32, 32, sisxvtvxposition
},
272 {XvSettable
| XvGettable
, -32, 32, sisxvtvyposition
},
273 {XvSettable
| XvGettable
, 0, 1, sisxvdisablegfx
},
274 {XvSettable
| XvGettable
, 0, 1, sisxvdisablegfxlr
},
275 {XvSettable
| XvGettable
, 0, 1, sisxvdisablecolorkey
},
276 {XvSettable
| XvGettable
, 0, 1, sisxvusechromakey
},
277 {XvSettable
| XvGettable
, 0, 1, sisxvinsidechromakey
},
278 {XvSettable
| XvGettable
, 0, 1, sisxvyuvchromakey
},
279 {XvSettable
| XvGettable
, 0, (1 << 24) - 1, sisxvchromamin
},
280 {XvSettable
| XvGettable
, 0, (1 << 24) - 1, sisxvchromamax
},
281 { XvGettable
, 0, 0xffffffff, sisxvqueryvbflags
},
282 { XvGettable
, 0, 0xffffffff, sisxvsdgetdriverversion
},
283 { XvGettable
, 0, 0xffffffff, sisxvsdgethardwareinfo
},
284 { XvGettable
, 0, 0xffffffff, sisxvsdgetbusid
},
285 { XvGettable
, 0, 0xffffffff, sisxvsdqueryvbflagsversion
},
286 { XvGettable
, 0, 0xffffffff, sisxvsdgetsdflags
},
287 {XvSettable
| XvGettable
, 0, 0xffffffff, sisxvsdunlocksisdirect
},
288 {XvSettable
, 0, 0xffffffff, sisxvsdsetvbflags
},
289 { XvGettable
, 0, 0xffffffff, sisxvsdquerydetecteddevices
},
290 {XvSettable
| XvGettable
, 0, 1, sisxvsdcrt1status
},
291 {XvSettable
, 0, 0xffffffff, sisxvsdcheckmodeindexforcrt2
},
292 { XvGettable
, 0, 0xffffffff, sisxvsdresultcheckmodeindexforcrt2
},
293 {XvSettable
| XvGettable
, 0, 4, sisxvsdsisantiflicker
},
294 {XvSettable
| XvGettable
, 0, 15, sisxvsdsissaturation
},
295 {XvSettable
| XvGettable
, 0, 15, sisxvsdsisedgeenhance
},
296 {XvSettable
| XvGettable
, -128, 127, sisxvsdsiscolcalibf
},
297 {XvSettable
| XvGettable
, -120, 120, sisxvsdsiscolcalibc
},
298 {XvSettable
| XvGettable
, 0, 1, sisxvsdsiscfilter
},
299 {XvSettable
| XvGettable
, 0, 8, sisxvsdsisyfilter
},
300 {XvSettable
| XvGettable
, 0, 15, sisxvsdchcontrast
},
301 {XvSettable
| XvGettable
, 0, 15, sisxvsdchtextenhance
},
302 {XvSettable
| XvGettable
, 0, 15, sisxvsdchchromaflickerfilter
},
303 {XvSettable
| XvGettable
, 0, 15, sisxvsdchlumaflickerfilter
},
304 {XvSettable
| XvGettable
, 0, 1, sisxvsdchcvbscolor
},
305 {XvSettable
| XvGettable
, 0, 3, sisxvsdchoverscan
},
306 {XvSettable
| XvGettable
, 0, 3, sisxvsdenablegamma
},
307 {XvSettable
| XvGettable
, -16, 16, sisxvsdtvxscale
},
308 {XvSettable
| XvGettable
, -4, 3, sisxvsdtvyscale
},
309 { XvGettable
, 0, 0xffffffff, sisxvsdgetscreensize
},
310 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrir
},
311 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrig
},
312 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrib
},
313 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrir
},
314 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrig
},
315 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrib
},
316 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrir2
},
317 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrig2
},
318 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrib2
},
319 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrir2
},
320 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrig2
},
321 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrib2
},
323 SIS_CP_VIDEO_ATTRIBUTES
327 static XF86AttributeRec SISAttributes_315
[NUM_ATTRIBUTES_315
] =
329 {XvSettable
| XvGettable
, 0, (1 << 24) - 1, sisxvcolorkey
},
330 {XvSettable
| XvGettable
, -128, 127, sisxvbrightness
},
331 {XvSettable
| XvGettable
, 0, 7, sisxvcontrast
},
332 {XvSettable
| XvGettable
, -7, 7, sisxvsaturation
},
333 {XvSettable
| XvGettable
, -8, 7, sisxvhue
},
334 {XvSettable
| XvGettable
, 0, 1, sisxvautopaintcolorkey
},
335 {XvSettable
, 0, 0, sisxvsetdefaults
},
336 {XvSettable
| XvGettable
, -32, 32, sisxvtvxposition
},
337 {XvSettable
| XvGettable
, -32, 32, sisxvtvyposition
},
338 {XvSettable
| XvGettable
, 100, 10000, sisxvgammared
},
339 {XvSettable
| XvGettable
, 100, 10000, sisxvgammagreen
},
340 {XvSettable
| XvGettable
, 100, 10000, sisxvgammablue
},
341 {XvSettable
| XvGettable
, 0, 1, sisxvdisablegfx
},
342 {XvSettable
| XvGettable
, 0, 1, sisxvdisablegfxlr
},
343 {XvSettable
| XvGettable
, 0, 1, sisxvdisablecolorkey
},
344 {XvSettable
| XvGettable
, 0, 1, sisxvusechromakey
},
345 {XvSettable
| XvGettable
, 0, 1, sisxvinsidechromakey
},
346 {XvSettable
| XvGettable
, 0, (1 << 24) - 1, sisxvchromamin
},
347 {XvSettable
| XvGettable
, 0, (1 << 24) - 1, sisxvchromamax
},
348 { XvGettable
, 0, 0xffffffff, sisxvqueryvbflags
},
349 { XvGettable
, 0, 0xffffffff, sisxvsdgetdriverversion
},
350 { XvGettable
, 0, 0xffffffff, sisxvsdgethardwareinfo
},
351 { XvGettable
, 0, 0xffffffff, sisxvsdgetbusid
},
352 { XvGettable
, 0, 0xffffffff, sisxvsdqueryvbflagsversion
},
353 { XvGettable
, 0, 0xffffffff, sisxvsdgetsdflags
},
354 {XvSettable
| XvGettable
, 0, 0xffffffff, sisxvsdunlocksisdirect
},
355 {XvSettable
, 0, 0xffffffff, sisxvsdsetvbflags
},
356 { XvGettable
, 0, 0xffffffff, sisxvsdquerydetecteddevices
},
357 {XvSettable
| XvGettable
, 0, 1, sisxvsdcrt1status
},
358 {XvSettable
, 0, 0xffffffff, sisxvsdcheckmodeindexforcrt2
},
359 { XvGettable
, 0, 0xffffffff, sisxvsdresultcheckmodeindexforcrt2
},
360 {XvSettable
| XvGettable
, 0, 4, sisxvsdsisantiflicker
},
361 {XvSettable
| XvGettable
, 0, 15, sisxvsdsissaturation
},
362 {XvSettable
| XvGettable
, 0, 15, sisxvsdsisedgeenhance
},
363 {XvSettable
| XvGettable
, -128, 127, sisxvsdsiscolcalibf
},
364 {XvSettable
| XvGettable
, -120, 120, sisxvsdsiscolcalibc
},
365 {XvSettable
| XvGettable
, 0, 1, sisxvsdsiscfilter
},
366 {XvSettable
| XvGettable
, 0, 8, sisxvsdsisyfilter
},
367 {XvSettable
| XvGettable
, 0, 15, sisxvsdchcontrast
},
368 {XvSettable
| XvGettable
, 0, 15, sisxvsdchtextenhance
},
369 {XvSettable
| XvGettable
, 0, 15, sisxvsdchchromaflickerfilter
},
370 {XvSettable
| XvGettable
, 0, 15, sisxvsdchlumaflickerfilter
},
371 {XvSettable
| XvGettable
, 0, 1, sisxvsdchcvbscolor
},
372 {XvSettable
| XvGettable
, 0, 3, sisxvsdchoverscan
},
373 {XvSettable
| XvGettable
, 0, 7, sisxvsdenablegamma
},
374 {XvSettable
| XvGettable
, -16, 16, sisxvsdtvxscale
},
375 {XvSettable
| XvGettable
, -4, 3, sisxvsdtvyscale
},
376 { XvGettable
, 0, 0xffffffff, sisxvsdgetscreensize
},
377 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrir
},
378 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrig
},
379 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrib
},
380 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrir
},
381 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrig
},
382 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrib
},
383 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrir2
},
384 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrig2
},
385 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorebrib2
},
386 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrir2
},
387 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrig2
},
388 {XvSettable
| XvGettable
, 100, 10000, sisxvsdstorepbrib2
},
389 {XvSettable
| XvGettable
, 0, 1, sisxvsdhidehwcursor
},
391 {XvSettable
, 0, 0xffffffff, sisxvsetreg
},
394 SIS_CP_VIDEO_ATTRIBUTES
396 {XvSettable
| XvGettable
, 0, 1, sisxvswitchcrt
},
399 #define NUM_IMAGES_300 6
400 #define NUM_IMAGES_315 7 /* NV12 only - but does not work */
401 #define NUM_IMAGES_330 9 /* NV12 and NV21 */
402 #define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */
403 #define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */
404 #define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */
405 #define PIXEL_FMT_I420 FOURCC_I420 /* 0x30323449 */
406 #define PIXEL_FMT_RGB5 0x35315652
407 #define PIXEL_FMT_RGB6 0x36315652
408 #define PIXEL_FMT_YVYU 0x55595659 /* 315/330 only */
409 #define PIXEL_FMT_NV12 0x3231564e /* 330 only */
410 #define PIXEL_FMT_NV21 0x3132564e /* 330 only */
413 #define PIXEL_FMT_RAW8 0x38574152
415 static XF86ImageRec SISImages
[NUM_IMAGES_330
] =
417 XVIMAGE_YUY2
, /* If order is changed, SISOffscreenImages must be adapted */
427 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
431 /* 15, 0x001F, 0x03E0, 0x7C00, - incorrect! */
432 15, 0x7C00, 0x03E0, 0x001F,
437 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
445 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
449 /* 16, 0x001F, 0x07E0, 0xF800, - incorrect! */
450 16, 0xF800, 0x07E0, 0x001F,
455 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
463 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71},
472 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
480 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71},
489 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
497 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71},
506 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
515 unsigned char currentBuf
;
517 short drw_x
, drw_y
, drw_w
, drw_h
;
518 short src_x
, src_y
, src_w
, src_h
;
520 short srcPitch
, height
;
523 unsigned char contrast
;
529 Bool autopaintColorKey
;
535 Bool insidechromakey
, yuvchromakey
;
536 CARD32 chromamin
, chromamax
;
539 BOOLEAN overlayStatus
;
546 Bool hasTwoOverlays
; /* Chipset has two overlays */
547 Bool dualHeadMode
; /* We're running in DHM */
553 int crtnum
; /* 0=CRT1, 1=CRT2 */
555 Bool needToScale
; /* Need to scale video */
557 int shiftValue
; /* 315/330 series need word addr/pitch, 300 series double word */
559 short linebufMergeLimit
;
562 short oldx1
, oldx2
, oldy1
, oldy2
;
564 short oldx1_2
, oldx2_2
, oldy1_2
, oldy2_2
;
568 Bool grabbedByV4L
; /* V4L stuff */
572 int modeflags
; /* Flags field of current display mode */
575 Bool updatetvxpos
, updatetvypos
;
577 } SISPortPrivRec
, *SISPortPrivPtr
;
604 DisplayModePtr currentmode
;
619 CARD16 SCREENheight2
;
622 DisplayModePtr currentmode2
;
624 Bool DoFirst
, DoSecond
;
630 CARD8 contrastFactor
;
632 CARD8 (*VBlankActiveFunc
)(SISPtr
, SISPortPrivPtr
);
634 CARD32 (*GetScanLineFunc
)(SISPtr pSiS
);
638 /* The following are not used yet */
639 CARD16 SubPictHUSF
; /* Subpicture scaling */
643 CARD16 SubPictsrcW
; /* Subpicture source width */
644 CARD16 SubPictsrcH
; /* Subpicture source height */
645 BoxRec SubPictdstBox
; /* SubPicture destination box */
646 CARD32 SubPictAddr
; /* SubPicture address */
647 CARD32 SubPictPitch
; /* SubPicture pitch */
648 CARD32 SubPictOrigPitch
; /* SubPicture real pitch (needed for scaling twice) */
649 CARD32 SubPictPreset
; /* Subpicture Preset */
651 CARD32 MPEG_Y
; /* MPEG Y Buffer Addr */
652 CARD32 MPEG_UV
; /* MPEG UV Buffer Addr */
655 } SISOverlayRec
, *SISOverlayPtr
;
659 /****************************************************************************
660 * Raw register access : These routines directly interact with the sis's
661 * control aperature. Must not be called until after
662 * the board's pci memory has been mapped.
663 ****************************************************************************/
666 static CARD32
_sisread(SISPtr pSiS
, CARD32 reg
)
668 return *(pSiS
->IOBase
+ reg
);
671 static void _siswrite(SISPtr pSiS
, CARD32 reg
, CARD32 data
)
673 *(pSiS
->IOBase
+ reg
) = data
;
677 static CARD8
getsrreg(SISPtr pSiS
, CARD8 reg
)
680 inSISIDXREG(SISSR
, reg
, ret
);
684 static CARD8
getvideoreg(SISPtr pSiS
, CARD8 reg
)
687 inSISIDXREG(SISVID
, reg
, ret
);
691 static __inline
void setvideoreg(SISPtr pSiS
, CARD8 reg
, CARD8 data
)
693 outSISIDXREG(SISVID
, reg
, data
);
696 static __inline
void setvideoregmask(SISPtr pSiS
, CARD8 reg
, CARD8 data
, CARD8 mask
)
699 inSISIDXREG(SISVID
, reg
, old
);
700 data
= (data
& mask
) | (old
& (~mask
));
701 outSISIDXREG(SISVID
, reg
, data
);
704 static void setsrregmask(SISPtr pSiS
, CARD8 reg
, CARD8 data
, CARD8 mask
)
708 inSISIDXREG(SISSR
, reg
, old
);
709 data
= (data
& mask
) | (old
& (~mask
));
710 outSISIDXREG(SISSR
, reg
, data
);
714 static CARD8
vblank_active_CRT1(SISPtr pSiS
, SISPortPrivPtr pPriv
)
716 return(inSISREG(SISINPSTAT
) & 0x08);
719 static CARD8
vblank_active_CRT2(SISPtr pSiS
, SISPortPrivPtr pPriv
)
723 if(pPriv
->bridgeIsSlave
) return(vblank_active_CRT1(pSiS
, pPriv
));
725 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
726 inSISIDXREG(SISPART1
, 0x30, ret
);
728 inSISIDXREG(SISPART1
, 0x25, ret
);
730 return((ret
& 0x02) ^ 0x02);
733 /* Scanline - unused */
735 static CARD32
get_scanline_CRT1(SISPtr pSiS
)
739 _siswrite (pSiS
, REG_PRIM_CRT_COUNTER
, 0x00000001);
740 line
= _sisread (pSiS
, REG_PRIM_CRT_COUNTER
);
742 return ((line
>> 16) & 0x07FF);
745 static CARD32
get_scanline_CRT2(SISPtr pSiS
)
749 line
= (CARD32
)(getsisreg(pSiS
, SISPART1
, Index_CRT2_FC_VCount1
) & 0x70) * 16
750 + getsisreg(pSiS
, SISPART1
, Index_CRT2_FC_VCount
);
757 SiSComputeXvGamma(SISPtr pSiS
)
760 double red
= 1.0 / (double)((double)pSiS
->XvGammaRed
/ 1000);
761 double green
= 1.0 / (double)((double)pSiS
->XvGammaGreen
/ 1000);
762 double blue
= 1.0 / (double)((double)pSiS
->XvGammaBlue
/ 1000);
764 for(i
= 0; i
<= num
; i
++) {
765 pSiS
->XvGammaRampRed
[i
] =
766 (red
== 1.0) ? i
: (CARD8
)(pow((double)i
/ (double)num
, red
) * (double)num
+ 0.5);
768 pSiS
->XvGammaRampGreen
[i
] =
769 (green
== 1.0) ? i
: (CARD8
)(pow((double)i
/ (double)num
, green
) * (double)num
+ 0.5);
771 pSiS
->XvGammaRampBlue
[i
] =
772 (blue
== 1.0) ? i
: (CARD8
)(pow((double)i
/ (double)num
, blue
) * (double)num
+ 0.5);
777 SiSSetXvGamma(SISPtr pSiS
)
780 unsigned char backup
= getsrreg(pSiS
, 0x1f);
781 setsrregmask(pSiS
, 0x1f, 0x08, 0x18);
782 for(i
= 0; i
<= 255; i
++) {
783 MMIO_OUT32(pSiS
->IOBase
, 0x8570,
785 (pSiS
->XvGammaRampBlue
[i
] << 16) |
786 (pSiS
->XvGammaRampGreen
[i
] << 8) |
787 pSiS
->XvGammaRampRed
[i
]);
789 setsrregmask(pSiS
, 0x1f, backup
, 0xff);
793 SiSUpdateXvGamma(SISPtr pSiS
, SISPortPrivPtr pPriv
)
795 unsigned char sr7
= getsrreg(pSiS
, 0x07);
797 if(!pSiS
->XvGamma
) return;
798 if(!(pSiS
->MiscFlags
& MISC_CRT1OVERLAYGAMMA
)) return;
801 if((pPriv
->dualHeadMode
) && (!pSiS
->SecondHead
)) return;
804 if(!(sr7
& 0x04)) return;
806 SiSComputeXvGamma(pSiS
);
811 SISResetXvGamma(ScrnInfoPtr pScrn
)
813 SISPtr pSiS
= SISPTR(pScrn
);
814 SISPortPrivPtr pPriv
= GET_PORT_PRIVATE(pScrn
);
816 SiSUpdateXvGamma(pSiS
, pPriv
);
819 void SISInitVideo(ScreenPtr pScreen
)
821 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
822 XF86VideoAdaptorPtr
*adaptors
, *newAdaptors
= NULL
;
823 XF86VideoAdaptorPtr newAdaptor
= NULL
;
826 newAdaptor
= SISSetupImageVideo(pScreen
);
828 SISInitOffscreenImages(pScreen
);
830 num_adaptors
= xf86XVListGenericAdaptors(pScrn
, &adaptors
);
835 adaptors
= &newAdaptor
;
837 /* need to free this someplace */
838 newAdaptors
= xalloc((num_adaptors
+ 1) * sizeof(XF86VideoAdaptorPtr
*));
840 memcpy(newAdaptors
, adaptors
, num_adaptors
* sizeof(XF86VideoAdaptorPtr
));
841 newAdaptors
[num_adaptors
] = newAdaptor
;
842 adaptors
= newAdaptors
;
849 xf86XVScreenInit(pScreen
, adaptors
, num_adaptors
);
856 SISSetPortDefaults(ScrnInfoPtr pScrn
, SISPortPrivPtr pPriv
)
858 SISPtr pSiS
= SISPTR(pScrn
);
860 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;;
863 pPriv
->colorKey
= pSiS
->colorKey
= 0x000101fe;
864 pPriv
->videoStatus
= 0;
865 pPriv
->brightness
= pSiS
->XvDefBri
;
866 pPriv
->contrast
= pSiS
->XvDefCon
;
867 pPriv
->hue
= pSiS
->XvDefHue
;
868 pPriv
->saturation
= pSiS
->XvDefSat
;
869 pPriv
->autopaintColorKey
= TRUE
;
870 pPriv
->disablegfx
= pSiS
->XvDefDisableGfx
;
871 pPriv
->disablegfxlr
= pSiS
->XvDefDisableGfxLR
;
872 pSiS
->disablecolorkeycurrent
= pSiS
->XvDisableColorKey
;
873 pPriv
->usechromakey
= pSiS
->XvUseChromaKey
;
874 pPriv
->insidechromakey
= pSiS
->XvInsideChromaKey
;
875 pPriv
->yuvchromakey
= pSiS
->XvYUVChromaKey
;
876 pPriv
->chromamin
= pSiS
->XvChromaMin
;
877 pPriv
->chromamax
= pSiS
->XvChromaMax
;
878 if(pPriv
->dualHeadMode
) {
880 if(!pSiS
->SecondHead
) {
881 pPriv
->tvxpos
= pSiS
->tvxpos
;
882 pPriv
->tvypos
= pSiS
->tvypos
;
883 pPriv
->updatetvxpos
= TRUE
;
884 pPriv
->updatetvypos
= TRUE
;
888 pPriv
->tvxpos
= pSiS
->tvxpos
;
889 pPriv
->tvypos
= pSiS
->tvypos
;
890 pPriv
->updatetvxpos
= TRUE
;
891 pPriv
->updatetvypos
= TRUE
;
896 if(pPriv
->dualHeadMode
) {
899 pSiSEnt
->curxvcrtnum
=
900 pSiSEnt
->XvOnCRT2
? 1 : 0;
903 pPriv
->crtnum
= pSiS
->XvOnCRT2
? 1 : 0;
905 pSiS
->XvGammaRed
= pSiS
->XvGammaRedDef
;
906 pSiS
->XvGammaGreen
= pSiS
->XvGammaGreenDef
;
907 pSiS
->XvGammaBlue
= pSiS
->XvGammaBlueDef
;
908 SiSUpdateXvGamma(pSiS
, pPriv
);
912 SISResetVideo(ScrnInfoPtr pScrn
)
914 SISPtr pSiS
= SISPTR(pScrn
);
915 SISPortPrivPtr pPriv
= GET_PORT_PRIVATE(pScrn
);
917 /* Unlock registers */
919 sisSaveUnlockExtRegisterLock(pSiS
, NULL
, NULL
);
921 if(getvideoreg (pSiS
, Index_VI_Passwd
) != 0xa1) {
922 setvideoreg (pSiS
, Index_VI_Passwd
, 0x86);
923 if(getvideoreg (pSiS
, Index_VI_Passwd
) != 0xa1)
924 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
925 "Xv: Video password could not unlock registers\n");
928 /* Initialize first overlay (CRT1) ------------------------------- */
930 /* This bit has obviously a different meaning on 315 series (linebuffer-related) */
931 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
932 /* Write-enable video registers */
933 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x80, 0x81);
935 /* Select overlay 2, clear all linebuffer related bits */
936 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0xb1);
939 /* Disable overlay */
940 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
942 /* Disable bob de-interlacer and some strange bit */
943 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x82);
945 /* Select RGB chroma key format (300 series only) */
946 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
947 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x40);
950 /* Reset scale control and contrast */
951 /* (Enable DDA (interpolation)) */
952 setvideoregmask(pSiS
, Index_VI_Scale_Control
, 0x60, 0x60);
953 setvideoregmask(pSiS
, Index_VI_Contrast_Enh_Ctrl
, 0x04, 0x1F);
955 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Preset_Low
, 0x00);
956 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Preset_Middle
, 0x00);
957 setvideoreg(pSiS
, Index_VI_UV_Buf_Preset_Low
, 0x00);
958 setvideoreg(pSiS
, Index_VI_UV_Buf_Preset_Middle
, 0x00);
959 setvideoreg(pSiS
, Index_VI_Disp_Y_UV_Buf_Preset_High
, 0x00);
960 setvideoreg(pSiS
, Index_VI_Play_Threshold_Low
, 0x00);
961 setvideoreg(pSiS
, Index_VI_Play_Threshold_High
, 0x00);
963 if(pSiS
->Chipset
== PCI_CHIP_SIS330
) {
964 setvideoregmask(pSiS
, Index_VI_Key_Overlay_OP
, 0x00, 0x10);
965 } else if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
966 setvideoregmask(pSiS
, Index_VI_Key_Overlay_OP
, 0x00, 0xE0);
968 if(pSiS
->sishw_ext
.jChipType
== SIS_661
) {
969 setvideoregmask(pSiS
, Index_VI_V_Buf_Start_Over
, 0x2c, 0x3c);
972 if((pSiS
->ChipFlags
& SiSCF_Is65x
) || (pSiS
->Chipset
== PCI_CHIP_SIS660
)) {
973 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0x04);
976 /* Initialize second overlay (CRT2) - only for 300, 630/730, 550, M650/651, 661/741/660/760 */
977 if(pPriv
->hasTwoOverlays
) {
979 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
980 /* Write-enable video registers */
981 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x81, 0x81);
983 /* Select overlay 2, clear all linebuffer related bits */
984 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x01, 0xb1);
987 /* Disable overlay */
988 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
990 /* Disable bob de-interlacer and some strange bit */
991 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x82);
993 /* Select RGB chroma key format */
994 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
995 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x40);
998 /* Reset scale control and contrast */
999 /* (Enable DDA (interpolation)) */
1000 setvideoregmask(pSiS
, Index_VI_Scale_Control
, 0x60, 0x60);
1001 setvideoregmask(pSiS
, Index_VI_Contrast_Enh_Ctrl
, 0x04, 0x1F);
1003 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Preset_Low
, 0x00);
1004 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Preset_Middle
, 0x00);
1005 setvideoreg(pSiS
, Index_VI_UV_Buf_Preset_Low
, 0x00);
1006 setvideoreg(pSiS
, Index_VI_UV_Buf_Preset_Middle
, 0x00);
1007 setvideoreg(pSiS
, Index_VI_Disp_Y_UV_Buf_Preset_High
, 0x00);
1008 setvideoreg(pSiS
, Index_VI_Play_Threshold_Low
, 0x00);
1009 setvideoreg(pSiS
, Index_VI_Play_Threshold_High
, 0x00);
1011 if(pSiS
->Chipset
== PCI_CHIP_SIS330
) {
1012 setvideoregmask(pSiS
, Index_VI_Key_Overlay_OP
, 0x00, 0x10);
1013 } else if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
1014 setvideoregmask(pSiS
, Index_VI_Key_Overlay_OP
, 0x00, 0xE0);
1016 if(pSiS
->sishw_ext
.jChipType
== SIS_661
) {
1017 setvideoregmask(pSiS
, Index_VI_V_Buf_Start_Over
, 0x24, 0x3c);
1022 /* set default properties for overlay 1 (CRT1) -------------------------- */
1023 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0x01);
1024 setvideoregmask(pSiS
, Index_VI_Contrast_Enh_Ctrl
, 0x04, 0x07);
1025 setvideoreg(pSiS
, Index_VI_Brightness
, 0x20);
1026 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
1027 setvideoreg(pSiS
, Index_VI_Hue
, 0x00);
1028 setvideoreg(pSiS
, Index_VI_Saturation
, 0x00);
1031 /* set default properties for overlay 2(CRT2) -------------------------- */
1032 if(pPriv
->hasTwoOverlays
) {
1033 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x01, 0x01);
1034 setvideoregmask(pSiS
, Index_VI_Contrast_Enh_Ctrl
, 0x04, 0x07);
1035 setvideoreg(pSiS
, Index_VI_Brightness
, 0x20);
1036 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
1037 setvideoreg(pSiS
, Index_VI_Hue
, 0x00);
1038 setvideoreg(pSiS
, Index_VI_Saturation
, 0x00);
1042 /* Reset Xv gamma correction */
1043 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
1044 SiSUpdateXvGamma(pSiS
, pPriv
);
1048 /* Set display mode (single CRT1/CRT2, mirror).
1049 * MIRROR mode is only available on chipsets with two overlays.
1050 * On the other chipsets, if only CRT1 or only CRT2 are used,
1051 * the correct display CRT is chosen automatically. If both
1052 * CRT1 and CRT2 are connected, the user can choose between CRT1 and
1053 * CRT2 by using the option XvOnCRT2.
1056 set_dispmode(ScrnInfoPtr pScrn
, SISPortPrivPtr pPriv
)
1058 SISPtr pSiS
= SISPTR(pScrn
);
1060 pPriv
->dualHeadMode
= pPriv
->bridgeIsSlave
= FALSE
;
1062 if(SiSBridgeIsInSlaveMode(pScrn
)) pPriv
->bridgeIsSlave
= TRUE
;
1064 if( (pSiS
->VBFlags
& VB_DISPMODE_MIRROR
) ||
1065 ((pPriv
->bridgeIsSlave
) && (pSiS
->VBFlags
& DISPTYPE_DISP2
)) ) {
1066 if(pPriv
->hasTwoOverlays
)
1067 pPriv
->displayMode
= DISPMODE_MIRROR
; /* CRT1+CRT2 (2 overlays) */
1068 else if(pPriv
->crtnum
)
1069 pPriv
->displayMode
= DISPMODE_SINGLE2
; /* CRT2 only */
1071 pPriv
->displayMode
= DISPMODE_SINGLE1
; /* CRT1 only */
1074 if(pSiS
->DualHeadMode
) {
1075 pPriv
->dualHeadMode
= TRUE
;
1076 if(pSiS
->SecondHead
)
1077 pPriv
->displayMode
= DISPMODE_SINGLE1
; /* CRT1 only */
1079 pPriv
->displayMode
= DISPMODE_SINGLE2
; /* CRT2 only */
1082 if(pSiS
->VBFlags
& DISPTYPE_DISP1
) {
1083 pPriv
->displayMode
= DISPMODE_SINGLE1
; /* CRT1 only */
1085 pPriv
->displayMode
= DISPMODE_SINGLE2
; /* CRT2 only */
1091 set_disptype_regs(ScrnInfoPtr pScrn
, SISPortPrivPtr pPriv
)
1093 SISPtr pSiS
= SISPTR(pScrn
);
1095 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
1098 if(pPriv
->dualHeadMode
) crtnum
= pSiSEnt
->curxvcrtnum
;
1103 * Bit 7: Enable overlay 2 on CRT2
1104 * Bit 6: Enable overlay 1 on CRT2
1106 * Bit 7: DCLK/TCLK overlay 2
1107 * 0=DCLK (overlay on CRT1)
1108 * 1=TCLK (overlay on CRT2)
1109 * Bit 6: DCLK/TCLK overlay 1
1110 * 0=DCLK (overlay on CRT1)
1111 * 1=TCLK (overlay on CRT2)
1113 * On chipsets with two overlays, we can freely select and also
1114 * have a mirror mode. However, we use overlay 1 for CRT1 and
1115 * overlay 2 for CRT2.
1116 * ATTENTION: CRT2 can only take up to 1 (one) overlay. Setting
1117 * SR06/32 to 0xc0 DOES NOT WORK. THAT'S CONFIRMED.
1118 * Therefore, we use overlay 1 on CRT2 if in SINGLE2 mode.
1120 * For chipsets with only one overlay, user must choose whether
1121 * to display the overlay on CRT1 or CRT2 by setting XvOnCRT2
1122 * to TRUE (CRT2) or FALSE (CRT1). The driver does this auto-
1123 * matically if only CRT1 or only CRT2 is used.
1125 #ifdef UNLOCK_ALWAYS
1126 sisSaveUnlockExtRegisterLock(pSiS
, NULL
, NULL
);
1129 switch (pPriv
->displayMode
)
1131 case DISPMODE_SINGLE1
: /* CRT1-only mode: */
1132 if(pPriv
->hasTwoOverlays
) {
1133 if(pPriv
->dualHeadMode
) {
1134 setsrregmask(pSiS
, 0x06, 0x00, 0x40); /* overlay 1 -> CRT1 */
1135 setsrregmask(pSiS
, 0x32, 0x00, 0x40);
1137 setsrregmask(pSiS
, 0x06, 0x00, 0xc0); /* both overlays -> CRT1 */
1138 setsrregmask(pSiS
, 0x32, 0x00, 0xc0);
1142 if((!pPriv
->dualHeadMode
) || (crtnum
== 0)) {
1144 setsrregmask(pSiS
, 0x06, 0x00, 0xc0); /* only overlay -> CRT1 */
1145 setsrregmask(pSiS
, 0x32, 0x00, 0xc0);
1152 case DISPMODE_SINGLE2
: /* CRT2-only mode: */
1153 if(pPriv
->hasTwoOverlays
) {
1154 if(pPriv
->dualHeadMode
) {
1155 setsrregmask(pSiS
, 0x06, 0x80, 0x80); /* overlay 2 -> CRT2 */
1156 setsrregmask(pSiS
, 0x32, 0x80, 0x80);
1158 setsrregmask(pSiS
, 0x06, 0x40, 0xc0); /* overlay 1 -> CRT2 */
1159 setsrregmask(pSiS
, 0x32, 0xc0, 0xc0); /* (although both clocks for CRT2!) */
1163 if((!pPriv
->dualHeadMode
) || (crtnum
== 1)) {
1165 setsrregmask(pSiS
, 0x06, 0x40, 0xc0); /* only overlay -> CRT2 */
1166 setsrregmask(pSiS
, 0x32, 0x40, 0xc0);
1173 case DISPMODE_MIRROR
: /* CRT1+CRT2-mode: (only on chips with 2 overlays) */
1175 setsrregmask(pSiS
, 0x06, 0x80, 0xc0); /* overlay 1 -> CRT1, overlay 2 -> CRT2 */
1176 setsrregmask(pSiS
, 0x32, 0x80, 0xc0);
1182 set_allowswitchcrt(SISPtr pSiS
, SISPortPrivPtr pPriv
)
1184 if(pSiS
->hasTwoOverlays
) {
1185 pPriv
->AllowSwitchCRT
= FALSE
;
1187 pPriv
->AllowSwitchCRT
= TRUE
;
1188 if(pSiS
->XvOnCRT2
) {
1189 if(!(pSiS
->VBFlags
& DISPTYPE_DISP1
)) {
1190 pPriv
->AllowSwitchCRT
= FALSE
;
1193 if(!(pSiS
->VBFlags
& DISPTYPE_DISP2
)) {
1194 pPriv
->AllowSwitchCRT
= FALSE
;
1201 set_maxencoding(SISPtr pSiS
, SISPortPrivPtr pPriv
)
1203 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
1204 DummyEncoding
.width
= IMAGE_MAX_WIDTH_300
;
1205 DummyEncoding
.height
= IMAGE_MAX_HEIGHT_300
;
1207 DummyEncoding
.width
= IMAGE_MAX_WIDTH_315
;
1208 DummyEncoding
.height
= IMAGE_MAX_HEIGHT_315
;
1209 if(pPriv
->hasTwoOverlays
) {
1210 /* Only half width available if both overlays
1211 * are going to be used
1214 if(pSiS
->DualHeadMode
) {
1215 if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
1216 DummyEncoding
.width
= 1536;
1218 DummyEncoding
.width
>>= 1;
1223 if(pSiS
->MergedFB
) {
1224 if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
1225 DummyEncoding
.width
= 1536;
1227 DummyEncoding
.width
>>= 1;
1231 if(pPriv
->displayMode
== DISPMODE_MIRROR
) {
1232 if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
1233 DummyEncoding
.width
= 1536;
1235 DummyEncoding
.width
>>= 1;
1242 static XF86VideoAdaptorPtr
1243 SISSetupImageVideo(ScreenPtr pScreen
)
1245 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1246 SISPtr pSiS
= SISPTR(pScrn
);
1247 XF86VideoAdaptorPtr adapt
;
1248 SISPortPrivPtr pPriv
;
1250 if(!(adapt
= xcalloc(1, sizeof(XF86VideoAdaptorRec
) +
1251 sizeof(SISPortPrivRec
) +
1255 adapt
->type
= XvWindowMask
| XvInputMask
| XvImageMask
;
1256 adapt
->flags
= VIDEO_OVERLAID_IMAGES
| VIDEO_CLIP_TO_VIEWPORT
;
1257 adapt
->name
= "SIS 300/315/330 series Video Overlay";
1258 adapt
->nEncodings
= 1;
1259 adapt
->pEncodings
= &DummyEncoding
;
1261 adapt
->nFormats
= NUM_FORMATS
;
1262 adapt
->pFormats
= SISFormats
;
1264 adapt
->pPortPrivates
= (DevUnion
*)(&adapt
[1]);
1266 pPriv
= (SISPortPrivPtr
)(&adapt
->pPortPrivates
[1]);
1268 /* Setup chipset type helpers */
1269 if(pSiS
->hasTwoOverlays
) {
1270 pPriv
->hasTwoOverlays
= TRUE
;
1271 pPriv
->AllowSwitchCRT
= FALSE
;
1273 pPriv
->hasTwoOverlays
= FALSE
;
1274 pPriv
->AllowSwitchCRT
= TRUE
;
1275 if(pSiS
->XvOnCRT2
) {
1276 if(!(pSiS
->VBFlags
& DISPTYPE_DISP1
)) {
1277 pPriv
->AllowSwitchCRT
= FALSE
;
1280 if(!(pSiS
->VBFlags
& DISPTYPE_DISP2
)) {
1281 pPriv
->AllowSwitchCRT
= FALSE
;
1286 set_allowswitchcrt(pSiS
, pPriv
);
1288 adapt
->pPortPrivates
[0].ptr
= (pointer
)(pPriv
);
1289 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
1290 adapt
->nImages
= NUM_IMAGES_300
;
1291 adapt
->pAttributes
= SISAttributes_300
;
1292 adapt
->nAttributes
= NUM_ATTRIBUTES_300
;
1294 if(pSiS
->sishw_ext
.jChipType
>= SIS_330
) {
1295 adapt
->nImages
= NUM_IMAGES_330
;
1297 adapt
->nImages
= NUM_IMAGES_315
;
1299 adapt
->pAttributes
= SISAttributes_315
;
1300 adapt
->nAttributes
= NUM_ATTRIBUTES_315
;
1301 if(pPriv
->hasTwoOverlays
) adapt
->nAttributes
--;
1304 adapt
->pImages
= SISImages
;
1305 adapt
->PutVideo
= NULL
;
1306 adapt
->PutStill
= NULL
;
1307 adapt
->GetVideo
= NULL
;
1308 adapt
->GetStill
= NULL
;
1309 adapt
->StopVideo
= SISStopVideo
;
1310 adapt
->SetPortAttribute
= SISSetPortAttribute
;
1311 adapt
->GetPortAttribute
= SISGetPortAttribute
;
1312 adapt
->QueryBestSize
= SISQueryBestSize
;
1313 adapt
->PutImage
= SISPutImage
;
1314 adapt
->QueryImageAttributes
= SISQueryImageAttributes
;
1316 pPriv
->videoStatus
= 0;
1317 pPriv
->currentBuf
= 0;
1318 pPriv
->linear
= NULL
;
1319 pPriv
->grabbedByV4L
= FALSE
;
1320 pPriv
->NoOverlay
= FALSE
;
1321 pPriv
->PrevOverlay
= FALSE
;
1323 /* gotta uninit this someplace */
1324 #if defined(REGION_NULL)
1325 REGION_NULL(pScreen
, &pPriv
->clip
);
1327 REGION_INIT(pScreen
, &pPriv
->clip
, NullBox
, 0);
1330 pSiS
->adaptor
= adapt
;
1332 pSiS
->xvBrightness
= MAKE_ATOM(sisxvbrightness
);
1333 pSiS
->xvContrast
= MAKE_ATOM(sisxvcontrast
);
1334 pSiS
->xvColorKey
= MAKE_ATOM(sisxvcolorkey
);
1335 pSiS
->xvSaturation
= MAKE_ATOM(sisxvsaturation
);
1336 pSiS
->xvHue
= MAKE_ATOM(sisxvhue
);
1337 pSiS
->xvSwitchCRT
= MAKE_ATOM(sisxvswitchcrt
);
1338 pSiS
->xvAutopaintColorKey
= MAKE_ATOM(sisxvautopaintcolorkey
);
1339 pSiS
->xvSetDefaults
= MAKE_ATOM(sisxvsetdefaults
);
1340 pSiS
->xvDisableGfx
= MAKE_ATOM(sisxvdisablegfx
);
1341 pSiS
->xvDisableGfxLR
= MAKE_ATOM(sisxvdisablegfxlr
);
1342 pSiS
->xvTVXPosition
= MAKE_ATOM(sisxvtvxposition
);
1343 pSiS
->xvTVYPosition
= MAKE_ATOM(sisxvtvyposition
);
1344 pSiS
->xvGammaRed
= MAKE_ATOM(sisxvgammared
);
1345 pSiS
->xvGammaGreen
= MAKE_ATOM(sisxvgammagreen
);
1346 pSiS
->xvGammaBlue
= MAKE_ATOM(sisxvgammablue
);
1347 pSiS
->xvDisableColorkey
= MAKE_ATOM(sisxvdisablecolorkey
);
1348 pSiS
->xvUseChromakey
= MAKE_ATOM(sisxvusechromakey
);
1349 pSiS
->xvInsideChromakey
= MAKE_ATOM(sisxvinsidechromakey
);
1350 pSiS
->xvYUVChromakey
= MAKE_ATOM(sisxvyuvchromakey
);
1351 pSiS
->xvChromaMin
= MAKE_ATOM(sisxvchromamin
);
1352 pSiS
->xvChromaMax
= MAKE_ATOM(sisxvchromamax
);
1353 pSiS
->xv_QVF
= MAKE_ATOM(sisxvqueryvbflags
);
1354 pSiS
->xv_GDV
= MAKE_ATOM(sisxvsdgetdriverversion
);
1355 pSiS
->xv_GHI
= MAKE_ATOM(sisxvsdgethardwareinfo
);
1356 pSiS
->xv_GBI
= MAKE_ATOM(sisxvsdgetbusid
);
1357 pSiS
->xv_QVV
= MAKE_ATOM(sisxvsdqueryvbflagsversion
);
1358 pSiS
->xv_GSF
= MAKE_ATOM(sisxvsdgetsdflags
);
1359 pSiS
->xv_USD
= MAKE_ATOM(sisxvsdunlocksisdirect
);
1360 pSiS
->xv_SVF
= MAKE_ATOM(sisxvsdsetvbflags
);
1361 pSiS
->xv_QDD
= MAKE_ATOM(sisxvsdquerydetecteddevices
);
1362 pSiS
->xv_CT1
= MAKE_ATOM(sisxvsdcrt1status
);
1363 pSiS
->xv_CMD
= MAKE_ATOM(sisxvsdcheckmodeindexforcrt2
);
1364 pSiS
->xv_CMDR
= MAKE_ATOM(sisxvsdresultcheckmodeindexforcrt2
);
1365 pSiS
->xv_TAF
= MAKE_ATOM(sisxvsdsisantiflicker
);
1366 pSiS
->xv_TSA
= MAKE_ATOM(sisxvsdsissaturation
);
1367 pSiS
->xv_TEE
= MAKE_ATOM(sisxvsdsisedgeenhance
);
1368 pSiS
->xv_COC
= MAKE_ATOM(sisxvsdsiscolcalibc
);
1369 pSiS
->xv_COF
= MAKE_ATOM(sisxvsdsiscolcalibf
);
1370 pSiS
->xv_CFI
= MAKE_ATOM(sisxvsdsiscfilter
);
1371 pSiS
->xv_YFI
= MAKE_ATOM(sisxvsdsisyfilter
);
1372 pSiS
->xv_TCO
= MAKE_ATOM(sisxvsdchcontrast
);
1373 pSiS
->xv_TTE
= MAKE_ATOM(sisxvsdchtextenhance
);
1374 pSiS
->xv_TCF
= MAKE_ATOM(sisxvsdchchromaflickerfilter
);
1375 pSiS
->xv_TLF
= MAKE_ATOM(sisxvsdchlumaflickerfilter
);
1376 pSiS
->xv_TCC
= MAKE_ATOM(sisxvsdchcvbscolor
);
1377 pSiS
->xv_OVR
= MAKE_ATOM(sisxvsdchoverscan
);
1378 pSiS
->xv_SGA
= MAKE_ATOM(sisxvsdenablegamma
);
1379 pSiS
->xv_TXS
= MAKE_ATOM(sisxvsdtvxscale
);
1380 pSiS
->xv_TYS
= MAKE_ATOM(sisxvsdtvyscale
);
1381 pSiS
->xv_GSS
= MAKE_ATOM(sisxvsdgetscreensize
);
1382 pSiS
->xv_BRR
= MAKE_ATOM(sisxvsdstorebrir
);
1383 pSiS
->xv_BRG
= MAKE_ATOM(sisxvsdstorebrig
);
1384 pSiS
->xv_BRB
= MAKE_ATOM(sisxvsdstorebrib
);
1385 pSiS
->xv_PBR
= MAKE_ATOM(sisxvsdstorepbrir
);
1386 pSiS
->xv_PBG
= MAKE_ATOM(sisxvsdstorepbrig
);
1387 pSiS
->xv_PBB
= MAKE_ATOM(sisxvsdstorepbrib
);
1388 pSiS
->xv_BRR2
= MAKE_ATOM(sisxvsdstorebrir2
);
1389 pSiS
->xv_BRG2
= MAKE_ATOM(sisxvsdstorebrig2
);
1390 pSiS
->xv_BRB2
= MAKE_ATOM(sisxvsdstorebrib2
);
1391 pSiS
->xv_PBR2
= MAKE_ATOM(sisxvsdstorepbrir2
);
1392 pSiS
->xv_PBG2
= MAKE_ATOM(sisxvsdstorepbrig2
);
1393 pSiS
->xv_PBB2
= MAKE_ATOM(sisxvsdstorepbrib2
);
1394 pSiS
->xv_SHC
= MAKE_ATOM(sisxvsdhidehwcursor
);
1396 pSiS
->xv_STR
= MAKE_ATOM(sisxvsetreg
);
1402 pSiS
->xv_sisdirectunlocked
= 0;
1403 pSiS
->xv_sd_result
= 0;
1405 /* 300 series require double words for addresses and pitches,
1406 * 315/330 series require word.
1408 switch (pSiS
->VGAEngine
) {
1410 pPriv
->shiftValue
= 1;
1414 pPriv
->shiftValue
= 2;
1418 /* Set displayMode according to VBFlags */
1419 set_dispmode(pScrn
, pPriv
);
1421 /* Now for the linebuffer stuff.
1422 * All chipsets have a certain number of linebuffers, each of a certain
1423 * size. The number of buffers is per overlay.
1424 * Chip number size max video size
1426 * 630/730 2 ? 720x576
1427 * 315 2 960? 1920x1080
1428 * 650/740 2 960 ("120x128") 1920x1080
1429 * M650/651.. 4 480 1920x1080
1430 * 330 2 960 1920x1080
1431 * 661/741/760 4 768 1920x1080
1432 * The unit of size is unknown; I just know that a size of 480 limits
1433 * the video source width to 384. Beyond that, line buffers must be
1434 * merged (otherwise the video output is garbled).
1435 * To use the maximum width (eg 1920x1080 on the 315 series, including
1436 * the M650, 651 and later), *all* line buffers must be merged. Hence,
1437 * we can only use one overlay. This should be set up for modes where
1438 * either only CRT1 or only CRT2 is used.
1439 * If both overlays are going to be used (such as in modes were both
1440 * CRT1 and CRT2 are active), we are limited to the half of the
1441 * maximum width, or 1536 on 661/741/760.
1444 pPriv
->linebufMergeLimit
= LINEBUFLIMIT1
;
1445 if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
1446 pPriv
->linebufMergeLimit
= LINEBUFLIMIT3
;
1449 set_maxencoding(pSiS
, pPriv
);
1451 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
1452 pPriv
->linebufmask
= 0x11;
1454 pPriv
->linebufmask
= 0xb1;
1455 if(!(pPriv
->hasTwoOverlays
)) {
1456 /* On machines with only one overlay, the linebuffers are
1457 * generally larger, so our merging-limit is higher, too.
1459 pPriv
->linebufMergeLimit
= LINEBUFLIMIT2
;
1463 /* Reset the properties to their defaults */
1464 SISSetPortDefaults(pScrn
, pPriv
);
1466 /* Set SR(06, 32) registers according to DISPMODE */
1467 set_disptype_regs(pScrn
, pPriv
);
1469 SISResetVideo(pScrn
);
1470 pSiS
->ResetXv
= SISResetVideo
;
1471 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
1472 pSiS
->ResetXvGamma
= SISResetXvGamma
;
1478 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0)
1480 RegionsEqual(RegionPtr A
, RegionPtr B
)
1485 num
= REGION_NUM_RECTS(A
);
1486 if(num
!= REGION_NUM_RECTS(B
))
1489 if((A
->extents
.x1
!= B
->extents
.x1
) ||
1490 (A
->extents
.x2
!= B
->extents
.x2
) ||
1491 (A
->extents
.y1
!= B
->extents
.y1
) ||
1492 (A
->extents
.y2
!= B
->extents
.y2
))
1495 dataA
= (int*)REGION_RECTS(A
);
1496 dataB
= (int*)REGION_RECTS(B
);
1499 if((dataA
[0] != dataB
[0]) || (dataA
[1] != dataB
[1]))
1510 SISSetPortAttribute(ScrnInfoPtr pScrn
, Atom attribute
,
1511 INT32 value
, pointer data
)
1513 SISPortPrivPtr pPriv
= (SISPortPrivPtr
)data
;
1514 SISPtr pSiS
= SISPTR(pScrn
);
1516 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;;
1519 if(attribute
== pSiS
->xvBrightness
) {
1520 if((value
< -128) || (value
> 127))
1522 pPriv
->brightness
= value
;
1523 } else if(attribute
== pSiS
->xvContrast
) {
1524 if((value
< 0) || (value
> 7))
1526 pPriv
->contrast
= value
;
1527 } else if(attribute
== pSiS
->xvColorKey
) {
1528 pPriv
->colorKey
= pSiS
->colorKey
= value
;
1529 REGION_EMPTY(pScrn
->pScreen
, &pPriv
->clip
);
1530 } else if(attribute
== pSiS
->xvAutopaintColorKey
) {
1531 if((value
< 0) || (value
> 1))
1533 pPriv
->autopaintColorKey
= value
;
1534 } else if(attribute
== pSiS
->xvSetDefaults
) {
1535 SISSetPortDefaults(pScrn
, pPriv
);
1536 } else if(attribute
== pSiS
->xvDisableGfx
) {
1537 if((value
< 0) || (value
> 1))
1539 pPriv
->disablegfx
= value
;
1540 } else if(attribute
== pSiS
->xvDisableGfxLR
) {
1541 if((value
< 0) || (value
> 1))
1543 pPriv
->disablegfxlr
= value
;
1544 } else if(attribute
== pSiS
->xvTVXPosition
) {
1545 if((value
< -32) || (value
> 32))
1547 pPriv
->tvxpos
= value
;
1548 if(pSiS
->xv_sisdirectunlocked
) {
1549 SiS_SetTVxposoffset(pScrn
, pPriv
->tvxpos
);
1550 pPriv
->updatetvxpos
= FALSE
;
1552 pSiS
->tvxpos
= pPriv
->tvxpos
;
1554 if(pPriv
->dualHeadMode
) pSiSEnt
->tvxpos
= pPriv
->tvxpos
;
1556 pPriv
->updatetvxpos
= TRUE
;
1558 } else if(attribute
== pSiS
->xvTVYPosition
) {
1559 if((value
< -32) || (value
> 32))
1561 pPriv
->tvypos
= value
;
1562 if(pSiS
->xv_sisdirectunlocked
) {
1563 SiS_SetTVyposoffset(pScrn
, pPriv
->tvypos
);
1564 pPriv
->updatetvypos
= FALSE
;
1566 pSiS
->tvypos
= pPriv
->tvypos
;
1568 if(pPriv
->dualHeadMode
) pSiSEnt
->tvypos
= pPriv
->tvypos
;
1570 pPriv
->updatetvypos
= TRUE
;
1572 } else if(attribute
== pSiS
->xvDisableColorkey
) {
1573 if((value
< 0) || (value
> 1))
1575 pSiS
->disablecolorkeycurrent
= value
;
1576 } else if(attribute
== pSiS
->xvUseChromakey
) {
1577 if((value
< 0) || (value
> 1))
1579 pPriv
->usechromakey
= value
;
1580 } else if(attribute
== pSiS
->xvInsideChromakey
) {
1581 if((value
< 0) || (value
> 1))
1583 pPriv
->insidechromakey
= value
;
1584 } else if(attribute
== pSiS
->xvYUVChromakey
) {
1585 if((value
< 0) || (value
> 1))
1587 pPriv
->yuvchromakey
= value
;
1588 } else if(attribute
== pSiS
->xvChromaMin
) {
1589 pPriv
->chromamin
= value
;
1590 } else if(attribute
== pSiS
->xvChromaMax
) {
1591 pPriv
->chromamax
= value
;
1592 } else if(attribute
== pSiS
->xv_USD
) {
1593 if(pSiS
->enablesisctrl
) {
1594 if(value
== SIS_DIRECTKEY
) {
1595 pSiS
->xv_sisdirectunlocked
++;
1596 } else if(pSiS
->xv_sisdirectunlocked
) {
1597 pSiS
->xv_sisdirectunlocked
--;
1600 pSiS
->xv_sisdirectunlocked
= 0;
1602 } else if(attribute
== pSiS
->xv_SVF
) {
1604 if(!pPriv
->dualHeadMode
)
1606 if(pSiS
->xv_sisdirectunlocked
) {
1607 SISSwitchCRT2Type(pScrn
, (unsigned long)value
);
1608 set_dispmode(pScrn
, pPriv
);
1609 set_allowswitchcrt(pSiS
, pPriv
);
1610 set_maxencoding(pSiS
, pPriv
);
1612 } else if(attribute
== pSiS
->xv_CT1
) {
1614 if(!pPriv
->dualHeadMode
)
1616 if(pSiS
->xv_sisdirectunlocked
) {
1617 SISSwitchCRT1Status(pScrn
, (unsigned long)value
);
1618 set_dispmode(pScrn
, pPriv
);
1619 set_allowswitchcrt(pSiS
, pPriv
);
1620 set_maxencoding(pSiS
, pPriv
);
1622 } else if(attribute
== pSiS
->xv_TAF
) {
1623 if(pSiS
->xv_sisdirectunlocked
) {
1624 SiS_SetSISTVantiflicker(pScrn
, (int)value
);
1626 } else if(attribute
== pSiS
->xv_TSA
) {
1627 if(pSiS
->xv_sisdirectunlocked
) {
1628 SiS_SetSISTVsaturation(pScrn
, (int)value
);
1630 } else if(attribute
== pSiS
->xv_TEE
) {
1631 if(pSiS
->xv_sisdirectunlocked
) {
1632 SiS_SetSISTVedgeenhance(pScrn
, (int)value
);
1634 } else if(attribute
== pSiS
->xv_CFI
) {
1635 if(pSiS
->xv_sisdirectunlocked
) {
1636 SiS_SetSISTVcfilter(pScrn
, value
? 1 : 0);
1638 } else if(attribute
== pSiS
->xv_YFI
) {
1639 if(pSiS
->xv_sisdirectunlocked
) {
1640 SiS_SetSISTVyfilter(pScrn
, value
);
1642 } else if(attribute
== pSiS
->xv_COC
) {
1643 if(pSiS
->xv_sisdirectunlocked
) {
1644 SiS_SetSISTVcolcalib(pScrn
, (int)value
, TRUE
);
1646 } else if(attribute
== pSiS
->xv_COF
) {
1647 if(pSiS
->xv_sisdirectunlocked
) {
1648 SiS_SetSISTVcolcalib(pScrn
, (int)value
, FALSE
);
1650 } else if(attribute
== pSiS
->xv_TCO
) {
1651 if(pSiS
->xv_sisdirectunlocked
) {
1652 SiS_SetCHTVcontrast(pScrn
, (int)value
);
1654 } else if(attribute
== pSiS
->xv_TTE
) {
1655 if(pSiS
->xv_sisdirectunlocked
) {
1656 SiS_SetCHTVtextenhance(pScrn
, (int)value
);
1658 } else if(attribute
== pSiS
->xv_TCF
) {
1659 if(pSiS
->xv_sisdirectunlocked
) {
1660 SiS_SetCHTVchromaflickerfilter(pScrn
, (int)value
);
1662 } else if(attribute
== pSiS
->xv_TLF
) {
1663 if(pSiS
->xv_sisdirectunlocked
) {
1664 SiS_SetCHTVlumaflickerfilter(pScrn
, (int)value
);
1666 } else if(attribute
== pSiS
->xv_TCC
) {
1667 if(pSiS
->xv_sisdirectunlocked
) {
1668 SiS_SetCHTVcvbscolor(pScrn
, value
? 1 : 0);
1670 } else if(attribute
== pSiS
->xv_OVR
) {
1671 if(pSiS
->xv_sisdirectunlocked
) {
1672 pSiS
->UseCHOverScan
= -1;
1673 pSiS
->OptTVSOver
= FALSE
;
1675 if(pSiS
->SiS_SD_Flags
& SiS_SD_SUPPORTSOVER
) {
1676 pSiS
->OptTVSOver
= TRUE
;
1678 pSiS
->UseCHOverScan
= 1;
1679 } else if(value
== 2) pSiS
->UseCHOverScan
= 1;
1680 else if(value
== 1) pSiS
->UseCHOverScan
= 0;
1682 } else if(attribute
== pSiS
->xv_CMD
) {
1683 if(pSiS
->xv_sisdirectunlocked
) {
1685 pSiS
->xv_sd_result
= (value
& 0xffffff00);
1686 result
= SISCheckModeIndexForCRT2Type(pScrn
, (unsigned short)(value
& 0xff),
1687 (unsigned short)((value
>> 8) & 0xff),
1689 pSiS
->xv_sd_result
|= (result
& 0xff);
1691 } else if(attribute
== pSiS
->xv_SGA
) {
1692 if(pSiS
->xv_sisdirectunlocked
) {
1693 Bool backup
= pSiS
->XvGamma
;
1694 pSiS
->CRT1gamma
= (value
& 0x01) ? TRUE
: FALSE
;
1695 pSiS
->CRT2gamma
= (value
& 0x02) ? TRUE
: FALSE
;
1696 pSiS
->XvGamma
= (value
& 0x04) ? TRUE
: FALSE
;
1698 if(pPriv
->dualHeadMode
) {
1699 pSiSEnt
->CRT1gamma
= pSiS
->CRT1gamma
;
1700 pSiSEnt
->CRT2gamma
= pSiS
->CRT2gamma
;
1703 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
1704 if(backup
!= pSiS
->XvGamma
) {
1705 SiSUpdateXvGamma(pSiS
, pPriv
);
1709 } else if(attribute
== pSiS
->xv_TXS
) {
1710 if((value
< -16) || (value
> 16))
1712 if(pSiS
->xv_sisdirectunlocked
) {
1713 SiS_SetTVxscale(pScrn
, value
);
1715 } else if(attribute
== pSiS
->xv_TYS
) {
1716 if((value
< -4) || (value
> 3))
1718 if(pSiS
->xv_sisdirectunlocked
) {
1719 SiS_SetTVyscale(pScrn
, value
);
1721 } else if(attribute
== pSiS
->xv_BRR
) {
1722 if((value
< 100) || (value
> 10000))
1724 if(pSiS
->xv_sisdirectunlocked
) {
1725 pSiS
->GammaBriR
= value
;
1727 } else if(attribute
== pSiS
->xv_BRG
) {
1728 if((value
< 100) || (value
> 10000))
1730 if(pSiS
->xv_sisdirectunlocked
) {
1731 pSiS
->GammaBriG
= value
;
1733 } else if(attribute
== pSiS
->xv_BRB
) {
1734 if((value
< 100) || (value
> 10000))
1736 if(pSiS
->xv_sisdirectunlocked
) {
1737 pSiS
->GammaBriB
= value
;
1739 } else if(attribute
== pSiS
->xv_PBR
) {
1740 if((value
< 100) || (value
> 10000))
1742 if(pSiS
->xv_sisdirectunlocked
) {
1743 pSiS
->GammaPBriR
= value
;
1745 } else if(attribute
== pSiS
->xv_PBG
) {
1746 if((value
< 100) || (value
> 10000))
1748 if(pSiS
->xv_sisdirectunlocked
) {
1749 pSiS
->GammaPBriG
= value
;
1751 } else if(attribute
== pSiS
->xv_PBB
) {
1752 if((value
< 100) || (value
> 10000))
1754 if(pSiS
->xv_sisdirectunlocked
) {
1755 pSiS
->GammaPBriB
= value
;
1757 } else if(attribute
== pSiS
->xv_BRR2
) {
1758 if((value
< 100) || (value
> 10000))
1760 if(pSiS
->xv_sisdirectunlocked
) {
1762 if(pPriv
->dualHeadMode
) pSiSEnt
->GammaBriR
= value
;
1765 } else if(attribute
== pSiS
->xv_BRG2
) {
1766 if((value
< 100) || (value
> 10000))
1768 if(pSiS
->xv_sisdirectunlocked
) {
1770 if(pPriv
->dualHeadMode
) pSiSEnt
->GammaBriG
= value
;
1773 } else if(attribute
== pSiS
->xv_BRB2
) {
1774 if((value
< 100) || (value
> 10000))
1776 if(pSiS
->xv_sisdirectunlocked
) {
1778 if(pPriv
->dualHeadMode
) pSiSEnt
->GammaBriB
= value
;
1781 } else if(attribute
== pSiS
->xv_PBR2
) {
1782 if((value
< 100) || (value
> 10000))
1784 if(pSiS
->xv_sisdirectunlocked
) {
1786 if(pPriv
->dualHeadMode
) pSiSEnt
->GammaPBriR
= value
;
1789 } else if(attribute
== pSiS
->xv_PBG2
) {
1790 if((value
< 100) || (value
> 10000))
1792 if(pSiS
->xv_sisdirectunlocked
) {
1794 if(pPriv
->dualHeadMode
) pSiSEnt
->GammaPBriG
= value
;
1797 } else if(attribute
== pSiS
->xv_PBB2
) {
1798 if((value
< 100) || (value
> 10000))
1800 if(pSiS
->xv_sisdirectunlocked
) {
1802 if(pPriv
->dualHeadMode
) pSiSEnt
->GammaPBriB
= value
;
1805 } else if(attribute
== pSiS
->xv_SHC
) {
1806 if(pSiS
->xv_sisdirectunlocked
) {
1807 Bool VisibleBackup
= pSiS
->HWCursorIsVisible
;
1808 pSiS
->HideHWCursor
= value
? TRUE
: FALSE
;
1809 if(pSiS
->CursorInfoPtr
) {
1812 (pSiS
->CursorInfoPtr
->HideCursor
)(pScrn
);
1814 (pSiS
->CursorInfoPtr
->ShowCursor
)(pScrn
);
1817 pSiS
->HWCursorIsVisible
= VisibleBackup
;
1821 } else if(attribute
== pSiS
->xv_STR
) {
1822 unsigned short port
;
1823 switch((value
& 0xff000000) >> 24) {
1824 case 0x00: port
= SISSR
; break;
1825 case 0x01: port
= SISPART1
; break;
1826 case 0x02: port
= SISPART2
; break;
1827 case 0x03: port
= SISPART3
; break;
1828 case 0x04: port
= SISPART4
; break;
1829 case 0x05: port
= SISCR
; break;
1830 case 0x06: port
= SISVID
; break;
1831 default: return BadValue
;
1833 outSISIDXREG(port
,((value
& 0x00ff0000) >> 16), ((value
& 0x0000ff00) >> 8));
1837 SIS_CP_VIDEO_SETATTRIBUTE
1839 } else if(pSiS
->VGAEngine
== SIS_315_VGA
) {
1840 if(attribute
== pSiS
->xvSwitchCRT
) {
1841 if(pPriv
->AllowSwitchCRT
) {
1842 if((value
< 0) || (value
> 1))
1844 pPriv
->crtnum
= value
;
1846 if(pPriv
->dualHeadMode
) pSiSEnt
->curxvcrtnum
= value
;
1849 } else if(attribute
== pSiS
->xvHue
) {
1850 if((value
< -8) || (value
> 7))
1853 } else if(attribute
== pSiS
->xvSaturation
) {
1854 if((value
< -7) || (value
> 7))
1856 pPriv
->saturation
= value
;
1857 } else if(attribute
== pSiS
->xvGammaRed
) {
1858 if((value
< 100) || (value
> 10000))
1860 pSiS
->XvGammaRed
= value
;
1861 SiSUpdateXvGamma(pSiS
, pPriv
);
1862 } else if(attribute
== pSiS
->xvGammaGreen
) {
1863 if((value
< 100) || (value
> 10000))
1865 pSiS
->XvGammaGreen
= value
;
1866 SiSUpdateXvGamma(pSiS
, pPriv
);
1867 } else if(attribute
== pSiS
->xvGammaBlue
) {
1868 if((value
< 100) || (value
> 10000))
1870 pSiS
->XvGammaBlue
= value
;
1871 SiSUpdateXvGamma(pSiS
, pPriv
);
1872 } else return BadMatch
;
1873 } else return BadMatch
;
1878 SISGetPortAttribute(
1884 SISPortPrivPtr pPriv
= (SISPortPrivPtr
)data
;
1885 SISPtr pSiS
= SISPTR(pScrn
);
1887 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;;
1890 if(attribute
== pSiS
->xvBrightness
) {
1891 *value
= pPriv
->brightness
;
1892 } else if(attribute
== pSiS
->xvContrast
) {
1893 *value
= pPriv
->contrast
;
1894 } else if(attribute
== pSiS
->xvColorKey
) {
1895 *value
= pPriv
->colorKey
;
1896 } else if(attribute
== pSiS
->xvAutopaintColorKey
) {
1897 *value
= (pPriv
->autopaintColorKey
) ? 1 : 0;
1898 } else if(attribute
== pSiS
->xvDisableGfx
) {
1899 *value
= (pPriv
->disablegfx
) ? 1 : 0;
1900 } else if(attribute
== pSiS
->xvDisableGfxLR
) {
1901 *value
= (pPriv
->disablegfxlr
) ? 1 : 0;
1902 } else if(attribute
== pSiS
->xvTVXPosition
) {
1903 *value
= SiS_GetTVxposoffset(pScrn
);
1904 } else if(attribute
== pSiS
->xvTVYPosition
) {
1905 *value
= SiS_GetTVyposoffset(pScrn
);
1906 } else if(attribute
== pSiS
->xvDisableColorkey
) {
1907 *value
= (pSiS
->disablecolorkeycurrent
) ? 1 : 0;
1908 } else if(attribute
== pSiS
->xvUseChromakey
) {
1909 *value
= (pPriv
->usechromakey
) ? 1 : 0;
1910 } else if(attribute
== pSiS
->xvInsideChromakey
) {
1911 *value
= (pPriv
->insidechromakey
) ? 1 : 0;
1912 } else if(attribute
== pSiS
->xvYUVChromakey
) {
1913 *value
= (pPriv
->yuvchromakey
) ? 1 : 0;
1914 } else if(attribute
== pSiS
->xvChromaMin
) {
1915 *value
= pPriv
->chromamin
;
1916 } else if(attribute
== pSiS
->xvChromaMax
) {
1917 *value
= pPriv
->chromamax
;
1918 } else if(attribute
== pSiS
->xv_QVF
) {
1919 *value
= pSiS
->VBFlags
;
1920 } else if(attribute
== pSiS
->xv_GDV
) {
1921 *value
= SISDRIVERIVERSION
;
1922 } else if(attribute
== pSiS
->xv_GHI
) {
1923 *value
= (pSiS
->ChipFlags
& 0xffff) | (pSiS
->sishw_ext
.jChipType
<< 16) | (pSiS
->ChipRev
<< 24);
1924 } else if(attribute
== pSiS
->xv_GBI
) {
1925 *value
= (pSiS
->PciInfo
->bus
<< 16) | (pSiS
->PciInfo
->device
<< 8) | pSiS
->PciInfo
->func
;
1926 } else if(attribute
== pSiS
->xv_QVV
) {
1927 *value
= SIS_VBFlagsVersion
;
1928 } else if(attribute
== pSiS
->xv_QDD
) {
1929 *value
= pSiS
->detectedCRT2Devices
;
1930 } else if(attribute
== pSiS
->xv_CT1
) {
1931 *value
= pSiS
->CRT1isoff
? 0 : 1;
1932 } else if(attribute
== pSiS
->xv_GSF
) {
1933 *value
= pSiS
->SiS_SD_Flags
;
1934 } else if(attribute
== pSiS
->xv_USD
) {
1935 *value
= pSiS
->xv_sisdirectunlocked
;
1936 } else if(attribute
== pSiS
->xv_TAF
) {
1937 *value
= SiS_GetSISTVantiflicker(pScrn
);
1938 } else if(attribute
== pSiS
->xv_TSA
) {
1939 *value
= SiS_GetSISTVsaturation(pScrn
);
1940 } else if(attribute
== pSiS
->xv_TEE
) {
1941 *value
= SiS_GetSISTVedgeenhance(pScrn
);
1942 } else if(attribute
== pSiS
->xv_CFI
) {
1943 *value
= SiS_GetSISTVcfilter(pScrn
);
1944 } else if(attribute
== pSiS
->xv_YFI
) {
1945 *value
= SiS_GetSISTVyfilter(pScrn
);
1946 } else if(attribute
== pSiS
->xv_COC
) {
1947 *value
= SiS_GetSISTVcolcalib(pScrn
, TRUE
);
1948 } else if(attribute
== pSiS
->xv_COF
) {
1949 *value
= SiS_GetSISTVcolcalib(pScrn
, FALSE
);
1950 } else if(attribute
== pSiS
->xv_TCO
) {
1951 *value
= SiS_GetCHTVcontrast(pScrn
);
1952 } else if(attribute
== pSiS
->xv_TTE
) {
1953 *value
= SiS_GetCHTVtextenhance(pScrn
);
1954 } else if(attribute
== pSiS
->xv_TCF
) {
1955 *value
= SiS_GetCHTVchromaflickerfilter(pScrn
);
1956 } else if(attribute
== pSiS
->xv_TLF
) {
1957 *value
= SiS_GetCHTVlumaflickerfilter(pScrn
);
1958 } else if(attribute
== pSiS
->xv_TCC
) {
1959 *value
= SiS_GetCHTVcvbscolor(pScrn
);
1960 } else if(attribute
== pSiS
->xv_CMDR
) {
1961 *value
= pSiS
->xv_sd_result
;
1962 } else if(attribute
== pSiS
->xv_OVR
) {
1964 if(pSiS
->OptTVSOver
== 1) *value
= 3;
1965 else if(pSiS
->UseCHOverScan
== 1) *value
= 2;
1966 else if(pSiS
->UseCHOverScan
== 0) *value
= 1;
1967 } else if(attribute
== pSiS
->xv_SGA
) {
1970 if(pPriv
->dualHeadMode
) {
1971 if(pSiSEnt
->CRT1gamma
) *value
|= 0x01;
1972 if(pSiSEnt
->CRT2gamma
) *value
|= 0x02;
1975 if(pSiS
->CRT1gamma
) *value
|= 0x01;
1976 if(pSiS
->CRT2gamma
) *value
|= 0x02;
1979 if(pSiS
->XvGamma
) *value
|= 0x04;
1981 } else if(attribute
== pSiS
->xv_TXS
) {
1982 *value
= SiS_GetTVxscale(pScrn
);
1983 } else if(attribute
== pSiS
->xv_TYS
) {
1984 *value
= SiS_GetTVyscale(pScrn
);
1985 } else if(attribute
== pSiS
->xv_GSS
) {
1986 *value
= (pScrn
->virtualX
<< 16) | pScrn
->virtualY
;
1987 } else if(attribute
== pSiS
->xv_BRR
) {
1988 *value
= pSiS
->GammaBriR
;
1989 } else if(attribute
== pSiS
->xv_BRG
) {
1990 *value
= pSiS
->GammaBriG
;
1991 } else if(attribute
== pSiS
->xv_BRB
) {
1992 *value
= pSiS
->GammaBriB
;
1993 } else if(attribute
== pSiS
->xv_PBR
) {
1994 *value
= pSiS
->GammaPBriR
;
1995 } else if(attribute
== pSiS
->xv_PBG
) {
1996 *value
= pSiS
->GammaPBriG
;
1997 } else if(attribute
== pSiS
->xv_PBB
) {
1998 *value
= pSiS
->GammaPBriB
;
1999 } else if(attribute
== pSiS
->xv_BRR2
) {
2001 if(pPriv
->dualHeadMode
) *value
= pSiSEnt
->GammaBriR
;
2004 *value
= pSiS
->GammaBriR
;
2005 } else if(attribute
== pSiS
->xv_BRG2
) {
2007 if(pPriv
->dualHeadMode
) *value
= pSiSEnt
->GammaBriG
;
2010 *value
= pSiS
->GammaBriG
;
2011 } else if(attribute
== pSiS
->xv_BRB2
) {
2013 if(pPriv
->dualHeadMode
) *value
= pSiSEnt
->GammaBriB
;
2016 *value
= pSiS
->GammaBriB
;
2017 } else if(attribute
== pSiS
->xv_PBR2
) {
2019 if(pPriv
->dualHeadMode
) *value
= pSiSEnt
->GammaPBriR
;
2022 *value
= pSiS
->GammaPBriR
;
2023 } else if(attribute
== pSiS
->xv_PBG2
) {
2025 if(pPriv
->dualHeadMode
) *value
= pSiSEnt
->GammaPBriG
;
2028 *value
= pSiS
->GammaPBriG
;
2029 } else if(attribute
== pSiS
->xv_PBB2
) {
2031 if(pPriv
->dualHeadMode
) *value
= pSiSEnt
->GammaPBriB
;
2034 *value
= pSiS
->GammaPBriB
;
2035 } else if(attribute
== pSiS
->xv_SHC
) {
2036 *value
= pSiS
->HideHWCursor
? 1 : 0;
2038 SIS_CP_VIDEO_GETATTRIBUTE
2040 } else if(pSiS
->VGAEngine
== SIS_315_VGA
) {
2041 if(attribute
== pSiS
->xvSwitchCRT
) {
2043 if(pPriv
->dualHeadMode
)
2044 *value
= pSiSEnt
->curxvcrtnum
;
2047 *value
= pPriv
->crtnum
;
2048 } else if(attribute
== pSiS
->xvHue
) {
2049 *value
= pPriv
->hue
;
2050 } else if(attribute
== pSiS
->xvSaturation
) {
2051 *value
= pPriv
->saturation
;
2052 } else if(attribute
== pSiS
->xvGammaRed
) {
2053 *value
= pSiS
->XvGammaRed
;
2054 } else if(attribute
== pSiS
->xvGammaGreen
) {
2055 *value
= pSiS
->XvGammaGreen
;
2056 } else if(attribute
== pSiS
->xvGammaBlue
) {
2057 *value
= pSiS
->XvGammaBlue
;
2058 } else return BadMatch
;
2059 } else return BadMatch
;
2063 #if 0 /* For future use */
2065 SiSHandleSiSDirectCommand(ScrnInfoPtr pScrn
, SISPortPrivPtr pPriv
, sisdirectcommand
*sdcbuf
)
2067 SISPtr pSiS
= SISPTR(pScrn
);
2071 if(sdcbuf
->sdc_id
!= SDC_ID
) return BadMatch
;
2073 j
= sdcbuf
->sdc_header
;
2074 j
+= sdcbuf
->sdc_command
;
2075 for(i
= 0; i
< SDC_NUM_PARM
; i
++) {
2076 j
+= sdcbuf
->sdc_parm
[i
];
2078 if(j
!= sdcbuf
->sdc_chksum
) {
2079 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
, "SiS Direct: Bad packet checksum\n");
2082 sdcbuf
->sdc_header
= SDC_RESULT_OK
;
2083 switch(sdcbuf
->sdc_command
) {
2084 case SDC_CMD_GETVERSION
:
2085 sdcbuf
->sdc_parm
[0] = SDC_VERSION
;
2087 case SDC_CMD_CHECKMODEFORCRT2
:
2088 j
= sdcbuf
->sdc_parm
[0];
2089 sdcbuf
->sdc_parm
[0] = SISCheckModeIndexForCRT2Type(pScrn
,
2090 (unsigned short)(j
& 0xff),
2091 (unsigned short)((j
>> 8) & 0xff),
2095 sdcbuf
->sdc_header
= SDC_RESULT_UNDEFCMD
;
2106 short vid_w
, short vid_h
,
2107 short drw_w
, short drw_h
,
2108 unsigned int *p_w
, unsigned int *p_h
,
2116 calc_scale_factor(SISOverlayPtr pOverlay
, ScrnInfoPtr pScrn
,
2117 SISPortPrivPtr pPriv
, int index
, int iscrt2
)
2119 SISPtr pSiS
= SISPTR(pScrn
);
2123 int dstW
= pOverlay
->dstBox
.x2
- pOverlay
->dstBox
.x1
;
2124 int dstH
= pOverlay
->dstBox
.y2
- pOverlay
->dstBox
.y1
;
2125 int srcW
= pOverlay
->srcW
;
2126 int srcH
= pOverlay
->srcH
;
2127 CARD16 LCDheight
= pSiS
->LCDheight
;
2128 int srcPitch
= pOverlay
->origPitch
;
2129 int origdstH
= dstH
;
2130 int modeflags
= pOverlay
->currentmode
->Flags
;
2132 /* Stretch image due to panel link scaling */
2133 if(pSiS
->VBFlags
& (CRT2_LCD
| CRT1_LCDA
)) {
2134 if(pPriv
->bridgeIsSlave
) {
2135 if(pSiS
->VBFlags
& (VB_LVDS
| VB_30xBDH
)) {
2136 if(pSiS
->MiscFlags
& MISC_PANELLINKSCALER
) {
2137 dstH
= (dstH
* LCDheight
) / pOverlay
->SCREENheight
;
2140 } else if((iscrt2
&& (pSiS
->VBFlags
& CRT2_LCD
)) ||
2141 (!iscrt2
&& (pSiS
->VBFlags
& CRT1_LCDA
))) {
2142 if(pSiS
->VBFlags
& (VB_LVDS
| VB_30xBDH
| CRT1_LCDA
)) {
2143 if(pSiS
->MiscFlags
& MISC_PANELLINKSCALER
) {
2144 dstH
= (dstH
* LCDheight
) / pOverlay
->SCREENheight
;
2145 if(pPriv
->displayMode
== DISPMODE_MIRROR
) flag
= 1;
2151 /* For double scan modes, we need to double the height
2152 * On 315 and 550 (?), we need to double the width as well.
2153 * Interlace mode vice versa.
2155 if(modeflags
& V_DBLSCAN
) {
2156 dstH
= origdstH
<< 1;
2158 if((pSiS
->sishw_ext
.jChipType
>= SIS_315H
) &&
2159 (pSiS
->sishw_ext
.jChipType
<= SIS_550
)) {
2163 if(modeflags
& V_INTERLACE
) {
2164 dstH
= origdstH
>> 1;
2170 if(pOverlay
->bobEnable
& 0x08) dstH
<<= 1;
2173 if(dstW
< OVERLAY_MIN_WIDTH
) dstW
= OVERLAY_MIN_WIDTH
;
2175 pOverlay
->HUSF
= 0x00;
2176 pOverlay
->IntBit
= 0x05;
2177 pOverlay
->wHPre
= 0;
2178 } else if(dstW
> srcW
) {
2180 pOverlay
->HUSF
= (srcW
<< 16) / dstW
;
2181 pOverlay
->IntBit
= 0x04;
2182 pOverlay
->wHPre
= 0;
2186 /* It seems, the hardware can't scale below factor .125 (=1/8) if the
2187 pitch isn't a multiple of 256.
2188 TODO: Test this on the 315 series!
2190 if((srcPitch
% 256) || (srcPitch
< 256)) {
2191 if(((dstW
* 1000) / srcW
) < 125) dstW
= tmpW
= ((srcW
* 125) / 1000) + 1;
2195 pOverlay
->IntBit
= 0x01;
2196 while(srcW
>= tmpW
) {
2200 pOverlay
->wHPre
= (CARD8
)(I
- 1);
2203 pOverlay
->HUSF
= ((srcW
- dstW
) << 16) / dstW
;
2205 pOverlay
->HUSF
= 0x00;
2208 if(dstH
< OVERLAY_MIN_HEIGHT
) dstH
= OVERLAY_MIN_HEIGHT
;
2210 pOverlay
->VUSF
= 0x00;
2211 pOverlay
->IntBit
|= 0x0A;
2212 } else if(dstH
> srcH
) {
2214 pOverlay
->VUSF
= (srcH
<< 16) / dstH
;
2215 pOverlay
->IntBit
|= 0x08;
2219 pOverlay
->IntBit
|= 0x02;
2222 pOverlay
->VUSF
= ((srcH
- dstH
) << 16) / dstH
;
2223 /* TW: Needed for LCD-scaling modes */
2224 if((flag
) && (mult
= (srcH
/ origdstH
)) >= 2) {
2225 pOverlay
->pitch
/= mult
;
2229 if(((pOverlay
->bobEnable
& 0x08) == 0x00) &&
2230 (((srcPitch
* I
)>>2) > 0xFFF)){
2231 pOverlay
->bobEnable
|= 0x08;
2235 if(((srcPitch
* I
)>>2) > 0xFFF) {
2236 I
= (0xFFF*2/srcPitch
);
2237 pOverlay
->VUSF
= 0xFFFF;
2241 pOverlay
->VUSF
= ((srcH
- dstH
) << 16) / dstH
;
2243 pOverlay
->VUSF
= 0x00;
2245 /* set video frame buffer offset */
2246 pOverlay
->pitch
= (CARD16
)(srcPitch
*I
);
2253 calc_scale_factor_2(SISOverlayPtr pOverlay
, ScrnInfoPtr pScrn
,
2254 SISPortPrivPtr pPriv
, int index
, int iscrt2
)
2256 SISPtr pSiS
= SISPTR(pScrn
);
2260 int dstW
= pOverlay
->dstBox2
.x2
- pOverlay
->dstBox2
.x1
;
2261 int dstH
= pOverlay
->dstBox2
.y2
- pOverlay
->dstBox2
.y1
;
2262 int srcW
= pOverlay
->srcW2
;
2263 int srcH
= pOverlay
->srcH2
;
2264 CARD16 LCDheight
= pSiS
->LCDheight
;
2265 int srcPitch
= pOverlay
->origPitch
;
2266 int origdstH
= dstH
;
2267 int modeflags
= pOverlay
->currentmode2
->Flags
;
2269 /* Stretch image due to panel link scaling */
2270 if(pSiS
->VBFlags
& CRT2_LCD
) {
2271 if(pSiS
->VBFlags
& (VB_LVDS
| VB_30xBDH
)) {
2272 if(pSiS
->MiscFlags
& MISC_PANELLINKSCALER
) {
2273 dstH
= (dstH
* LCDheight
) / pOverlay
->SCREENheight2
;
2278 /* For double scan modes, we need to double the height
2279 * On 315 and 550 (?), we need to double the width as well.
2280 * Interlace mode vice versa.
2282 if(modeflags
& V_DBLSCAN
) {
2283 dstH
= origdstH
<< 1;
2285 if((pSiS
->sishw_ext
.jChipType
>= SIS_315H
) &&
2286 (pSiS
->sishw_ext
.jChipType
<= SIS_550
)) {
2290 if(modeflags
& V_INTERLACE
) {
2291 dstH
= origdstH
>> 1;
2297 if(pOverlay
->bobEnable
& 0x08) dstH
<<= 1;
2300 if(dstW
< OVERLAY_MIN_WIDTH
) dstW
= OVERLAY_MIN_WIDTH
;
2302 pOverlay
->HUSF2
= 0x00;
2303 pOverlay
->IntBit2
= 0x05;
2304 pOverlay
->wHPre2
= 0;
2305 } else if(dstW
> srcW
) {
2307 pOverlay
->HUSF2
= (srcW
<< 16) / dstW
;
2308 pOverlay
->IntBit2
= 0x04;
2309 pOverlay
->wHPre2
= 0;
2313 /* It seems, the hardware can't scale below factor .125 (=1/8) if the
2314 pitch isn't a multiple of 256.
2315 TODO: Test this on the 315 series!
2317 if((srcPitch
% 256) || (srcPitch
< 256)) {
2318 if(((dstW
* 1000) / srcW
) < 125) dstW
= tmpW
= ((srcW
* 125) / 1000) + 1;
2322 pOverlay
->IntBit2
= 0x01;
2323 while(srcW
>= tmpW
) {
2327 pOverlay
->wHPre2
= (CARD8
)(I
- 1);
2330 pOverlay
->HUSF2
= ((srcW
- dstW
) << 16) / dstW
;
2332 pOverlay
->HUSF2
= 0x00;
2335 if(dstH
< OVERLAY_MIN_HEIGHT
) dstH
= OVERLAY_MIN_HEIGHT
;
2337 pOverlay
->VUSF2
= 0x00;
2338 pOverlay
->IntBit2
|= 0x0A;
2339 } else if(dstH
> srcH
) {
2341 pOverlay
->VUSF2
= (srcH
<< 16) / dstH
;
2342 pOverlay
->IntBit2
|= 0x08;
2346 pOverlay
->IntBit2
|= 0x02;
2349 pOverlay
->VUSF2
= ((srcH
- dstH
) << 16) / dstH
;
2350 /* Needed for LCD-scaling modes */
2351 if(flag
&& ((mult
= (srcH
/ origdstH
)) >= 2)) {
2352 pOverlay
->pitch2
/= mult
;
2356 if(((pOverlay
->bobEnable
& 0x08) == 0x00) &&
2357 (((srcPitch
* I
)>>2) > 0xFFF)){
2358 pOverlay
->bobEnable
|= 0x08;
2362 if(((srcPitch
* I
)>>2) > 0xFFF) {
2363 I
= (0xFFF*2/srcPitch
);
2364 pOverlay
->VUSF2
= 0xFFFF;
2368 pOverlay
->VUSF2
= ((srcH
- dstH
) << 16) / dstH
;
2370 pOverlay
->VUSF2
= 0x00;
2372 /* set video frame buffer offset */
2373 pOverlay
->pitch2
= (CARD16
)(srcPitch
*I
);
2380 calc_line_buf_size(CARD32 srcW
, CARD8 wHPre
, CARD32 pixelFormat
)
2386 if( (pixelFormat
== PIXEL_FMT_YV12
) ||
2387 (pixelFormat
== PIXEL_FMT_I420
) ||
2388 (pixelFormat
== PIXEL_FMT_NV12
) ||
2389 (pixelFormat
== PIXEL_FMT_NV21
) )
2391 preHIDF
= wHPre
& 0x07;
2395 if((line
& 0xffffff00) == line
)
2398 I
= (line
>> 8) + 1;
2399 return((CARD8
)(I
* 32 - 1));
2401 if((line
& 0xfffffe00) == line
)
2404 I
= (line
>> 9) + 1;
2405 return((CARD8
)(I
* 64 - 1));
2407 if((line
& 0xfffffc00) == line
)
2410 I
= (line
>> 10) + 1;
2411 return((CARD8
)(I
* 128 - 1));
2413 return((CARD8
)(255));
2415 if((line
& 0xffffff80) == line
)
2418 I
= (line
>> 7) + 1;
2419 return((CARD8
)(I
* 16 - 1));
2421 } else { /* YUV2, UYVY */
2422 if((line
& 0xffffff8) == line
)
2425 I
= (line
>> 3) + 1;
2426 return((CARD8
)(I
- 1));
2430 static __inline
void
2431 set_line_buf_size_1(SISOverlayPtr pOverlay
)
2433 pOverlay
->lineBufSize
= calc_line_buf_size(pOverlay
->srcW
,pOverlay
->wHPre
, pOverlay
->pixelFormat
);
2437 static __inline
void
2438 set_line_buf_size_2(SISOverlayPtr pOverlay
)
2440 pOverlay
->lineBufSize2
= calc_line_buf_size(pOverlay
->srcW2
,pOverlay
->wHPre2
, pOverlay
->pixelFormat
);
2444 merge_line_buf_mfb(SISPtr pSiS
, SISPortPrivPtr pPriv
, Bool enable1
, Bool enable2
,
2445 short width1
, short width2
, short limit
)
2447 unsigned char misc1
, misc2
, mask
= pPriv
->linebufmask
;
2449 if(pPriv
->hasTwoOverlays
) { /* This means we are in MIRROR mode */
2452 if(enable1
) misc1
= 0x04;
2454 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, misc2
, mask
);
2455 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, misc1
, 0x04);
2458 if(enable2
) misc1
= 0x04;
2460 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, misc2
, mask
);
2461 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, misc1
, 0x04);
2463 } else { /* This means we are either in SINGLE1 or SINGLE2 mode */
2466 if(enable1
|| enable2
) misc1
= 0x04;
2469 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, misc2
, mask
);
2470 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, misc1
, 0x04);
2476 /* About linebuffer merging:
2478 * For example the 651:
2479 * Each overlay has 4 line buffers, 384 bytes each (<-- Is that really correct? 1920 / 384 = 5 !!!)
2480 * If the source width is greater than 384, line buffers must be merged.
2481 * Dual merge: Only O1 usable (uses overlay 2's linebuffer), maximum width 384*2
2482 * Individual merge: Both overlays available, maximum width 384*2
2483 * All merge: Only overlay 1 available, maximum width = 384*4 (<--- should be 1920, is 1536...)
2486 * Normally: Dual merge: Individual merge
2487 * Overlay 1 Overlay 2 Overlay 1 only! Both overlays
2488 * ___1___ ___5___ ___1___ ___2___ -\ O1 ___1___ ___2___
2489 * ___2___ ___6___ ___3___ ___4___ \_ O 1 O1 ___3___ ___4___
2490 * ___3___ ___7___ ___5___ ___6___ / O2 ___5___ ___6___
2491 * ___4___ ___8___ ___7___ ___8___ -/ O2 ___7___ ___8___
2494 * All merge: ___1___ ___2___ ___3___ ___4___
2495 * (Overlay 1 only!) ___5___ ___6___ ___7___ ___8___
2497 * Individual merge is supported on all chipsets.
2498 * Dual merge is only supported on the 300 series and M650/651 and later.
2499 * All merge is only supported on the M650/651 and later.
2505 merge_line_buf(SISPtr pSiS
, SISPortPrivPtr pPriv
, Bool enable
, short width
, short limit
)
2507 unsigned char misc1
, misc2
, mask
= pPriv
->linebufmask
;
2509 if(enable
) { /* ----- enable linebuffer merge */
2511 switch(pPriv
->displayMode
){
2512 case DISPMODE_SINGLE1
:
2513 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
2514 if(pPriv
->dualHeadMode
) {
2522 if(pPriv
->hasTwoOverlays
) {
2523 if(pPriv
->dualHeadMode
) {
2527 if(width
> (limit
* 2)) {
2539 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, misc2
, mask
);
2540 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, misc1
, 0x04);
2543 case DISPMODE_SINGLE2
:
2544 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
2545 if(pPriv
->dualHeadMode
) {
2553 if(pPriv
->hasTwoOverlays
) {
2554 if(pPriv
->dualHeadMode
) {
2558 if(width
> (limit
* 2)) {
2570 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, misc2
, mask
);
2571 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, misc1
, 0x04);
2574 case DISPMODE_MIRROR
: /* This can only be on chips with 2 overlays */
2576 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, mask
);
2577 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x04, 0x04);
2578 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x01, mask
);
2579 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x04, 0x04);
2583 } else { /* ----- disable linebuffer merge */
2585 switch(pPriv
->displayMode
) {
2587 case DISPMODE_SINGLE1
:
2588 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, mask
);
2589 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x04);
2592 case DISPMODE_SINGLE2
:
2593 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
2594 if(pPriv
->dualHeadMode
) misc2
= 0x01;
2597 if(pPriv
->hasTwoOverlays
) {
2598 if(pPriv
->dualHeadMode
) misc2
= 0x01;
2604 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, misc2
, mask
);
2605 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x04);
2608 case DISPMODE_MIRROR
: /* This can only be on chips with 2 overlays */
2610 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, mask
);
2611 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x04);
2612 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x01, mask
);
2613 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x04);
2619 static __inline
void
2620 set_format(SISPtr pSiS
, SISOverlayPtr pOverlay
)
2624 switch (pOverlay
->pixelFormat
){
2625 case PIXEL_FMT_YV12
:
2626 case PIXEL_FMT_I420
:
2629 case PIXEL_FMT_YUY2
:
2632 case PIXEL_FMT_UYVY
:
2635 case PIXEL_FMT_YVYU
:
2638 case PIXEL_FMT_NV12
:
2641 case PIXEL_FMT_NV21
:
2644 case PIXEL_FMT_RGB5
: /* D[5:4] : 00 RGB555, 01 RGB 565 */
2647 case PIXEL_FMT_RGB6
:
2654 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, fmt
, 0xfc);
2657 static __inline
void
2658 set_colorkey(SISPtr pSiS
, CARD32 colorkey
)
2662 b
= (CARD8
)(colorkey
& 0xFF);
2663 g
= (CARD8
)((colorkey
>>8) & 0xFF);
2664 r
= (CARD8
)((colorkey
>>16) & 0xFF);
2666 setvideoreg(pSiS
, Index_VI_Overlay_ColorKey_Blue_Min
,(CARD8
)b
);
2667 setvideoreg(pSiS
, Index_VI_Overlay_ColorKey_Green_Min
,(CARD8
)g
);
2668 setvideoreg(pSiS
, Index_VI_Overlay_ColorKey_Red_Min
,(CARD8
)r
);
2670 setvideoreg(pSiS
, Index_VI_Overlay_ColorKey_Blue_Max
,(CARD8
)b
);
2671 setvideoreg(pSiS
, Index_VI_Overlay_ColorKey_Green_Max
,(CARD8
)g
);
2672 setvideoreg(pSiS
, Index_VI_Overlay_ColorKey_Red_Max
,(CARD8
)r
);
2675 static __inline
void
2676 set_chromakey(SISPtr pSiS
, CARD32 chromamin
, CARD32 chromamax
)
2681 b1
= (CARD8
)(chromamin
& 0xFF);
2682 g1
= (CARD8
)((chromamin
>>8) & 0xFF);
2683 r1
= (CARD8
)((chromamin
>>16) & 0xFF);
2684 b2
= (CARD8
)(chromamax
& 0xFF);
2685 g2
= (CARD8
)((chromamax
>>8) & 0xFF);
2686 r2
= (CARD8
)((chromamax
>>16) & 0xFF);
2688 setvideoreg(pSiS
, Index_VI_Overlay_ChromaKey_Blue_V_Min
,(CARD8
)b1
);
2689 setvideoreg(pSiS
, Index_VI_Overlay_ChromaKey_Green_U_Min
,(CARD8
)g1
);
2690 setvideoreg(pSiS
, Index_VI_Overlay_ChromaKey_Red_Y_Min
,(CARD8
)r1
);
2692 setvideoreg(pSiS
, Index_VI_Overlay_ChromaKey_Blue_V_Max
,(CARD8
)b2
);
2693 setvideoreg(pSiS
, Index_VI_Overlay_ChromaKey_Green_U_Max
,(CARD8
)g2
);
2694 setvideoreg(pSiS
, Index_VI_Overlay_ChromaKey_Red_Y_Max
,(CARD8
)r2
);
2697 static __inline
void
2698 set_brightness(SISPtr pSiS
, CARD8 brightness
)
2700 setvideoreg(pSiS
, Index_VI_Brightness
, brightness
);
2703 static __inline
void
2704 set_contrast(SISPtr pSiS
, CARD8 contrast
)
2706 setvideoregmask(pSiS
, Index_VI_Contrast_Enh_Ctrl
, contrast
, 0x07);
2709 /* 315 series and later only */
2710 static __inline
void
2711 set_saturation(SISPtr pSiS
, short saturation
)
2715 if(saturation
< 0) {
2717 saturation
= -saturation
;
2719 temp
|= (saturation
& 0x07);
2720 temp
|= ((saturation
& 0x07) << 4);
2722 setvideoreg(pSiS
, Index_VI_Saturation
, temp
);
2725 /* 315 series and later only */
2726 static __inline
void
2727 set_hue(SISPtr pSiS
, CARD8 hue
)
2729 setvideoregmask(pSiS
, Index_VI_Hue
, (hue
& 0x08) ? (hue
^ 0x07) : hue
, 0x0F);
2732 static __inline
void
2733 set_disablegfx(SISPtr pSiS
, Bool mybool
, SISOverlayPtr pOverlay
)
2735 /* This is not supported on M65x, 65x (x>0) or later */
2736 /* For CRT1 ONLY!!! */
2737 if((!(pSiS
->ChipFlags
& SiSCF_Is65x
)) && (pSiS
->Chipset
!= PCI_CHIP_SIS660
)) {
2738 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, mybool
? 0x04 : 0x00, 0x04);
2739 if(mybool
) pOverlay
->keyOP
= VI_ROP_Always
;
2743 static __inline
void
2744 set_disablegfxlr(SISPtr pSiS
, Bool mybool
, SISOverlayPtr pOverlay
)
2746 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, mybool
? 0x01 : 0x00, 0x01);
2747 if(mybool
) pOverlay
->keyOP
= VI_ROP_Always
;
2755 set_overlay(SISPtr pSiS
, SISOverlayPtr pOverlay
, SISPortPrivPtr pPriv
, int index
, int iscrt2
)
2757 ScrnInfoPtr pScrn
= pSiS
->pScrn
;
2760 CARD8 h_over
=0, v_over
=0;
2761 CARD16 top
, bottom
, left
, right
;
2762 CARD16 screenX
, screenY
;
2763 int modeflags
, watchdog
;
2768 if(pSiS
->MergedFB
&& iscrt2
) {
2769 screenX
= pOverlay
->currentmode2
->HDisplay
;
2770 screenY
= pOverlay
->currentmode2
->VDisplay
;
2771 modeflags
= pOverlay
->currentmode2
->Flags
;
2772 top
= pOverlay
->dstBox2
.y1
;
2773 bottom
= pOverlay
->dstBox2
.y2
;
2774 left
= pOverlay
->dstBox2
.x1
;
2775 right
= pOverlay
->dstBox2
.x2
;
2776 pitch
= pOverlay
->pitch2
>> pPriv
->shiftValue
;
2779 screenX
= pOverlay
->currentmode
->HDisplay
;
2780 screenY
= pOverlay
->currentmode
->VDisplay
;
2781 modeflags
= pOverlay
->currentmode
->Flags
;
2782 top
= pOverlay
->dstBox
.y1
;
2783 bottom
= pOverlay
->dstBox
.y2
;
2784 left
= pOverlay
->dstBox
.x1
;
2785 right
= pOverlay
->dstBox
.x2
;
2786 pitch
= pOverlay
->pitch
>> pPriv
->shiftValue
;
2791 if(bottom
> screenY
) {
2794 if(right
> screenX
) {
2798 /* DoubleScan modes require Y coordinates * 2 */
2799 if(modeflags
& V_DBLSCAN
) {
2803 /* Interlace modes require Y coordinates / 2 */
2804 if(modeflags
& V_INTERLACE
) {
2809 h_over
= (((left
>>8) & 0x0f) | ((right
>>4) & 0xf0));
2810 v_over
= (((top
>>8) & 0x0f) | ((bottom
>>4) & 0xf0));
2812 /* set line buffer size */
2814 if(pSiS
->MergedFB
&& iscrt2
)
2815 setvideoreg(pSiS
, Index_VI_Line_Buffer_Size
, pOverlay
->lineBufSize2
);
2818 setvideoreg(pSiS
, Index_VI_Line_Buffer_Size
, pOverlay
->lineBufSize
);
2820 /* set color key mode */
2821 setvideoregmask(pSiS
, Index_VI_Key_Overlay_OP
, pOverlay
->keyOP
, 0x0f);
2823 /* We don't have to wait for vertical retrace in all cases */
2824 if(pPriv
->mustwait
) {
2825 if((pSiS
->VGAEngine
== SIS_315_VGA
) && (index
)) {
2826 /* overlay 2 needs special treatment */
2827 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
2829 watchdog
= WATCHDOG_DELAY
;
2830 while(pOverlay
->VBlankActiveFunc(pSiS
, pPriv
) && --watchdog
);
2831 watchdog
= WATCHDOG_DELAY
;
2832 while((!pOverlay
->VBlankActiveFunc(pSiS
, pPriv
)) && --watchdog
);
2833 if(!watchdog
) xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
2834 "Xv: Waiting for vertical retrace timed-out\n");
2837 /* Unlock address registers */
2838 data
= getvideoreg(pSiS
, Index_VI_Control_Misc1
);
2839 setvideoreg(pSiS
, Index_VI_Control_Misc1
, data
| 0x20);
2840 /* Is this required? */
2841 setvideoreg(pSiS
, Index_VI_Control_Misc1
, data
| 0x20);
2843 /* Is this required? (seems so) */
2844 if((pSiS
->Chipset
== SIS_315_VGA
) && !index
)
2845 setvideoregmask(pSiS
, Index_VI_Control_Misc3
, 0x00, (1 << index
));
2847 /* Set Y buf pitch */
2848 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Pitch_Low
, (CARD8
)(pitch
));
2849 setvideoregmask(pSiS
, Index_VI_Disp_Y_UV_Buf_Pitch_Middle
, (CARD8
)(pitch
>> 8), 0x0f);
2851 /* Set Y start address */
2853 if(pSiS
->MergedFB
&& iscrt2
) {
2854 PSY
= pOverlay
->PSY2
;
2857 PSY
= pOverlay
->PSY
;
2859 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Start_Low
, (CARD8
)(PSY
));
2860 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Start_Middle
, (CARD8
)(PSY
>> 8));
2861 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Start_High
, (CARD8
)(PSY
>> 16));
2863 /* set 315 series overflow bits for Y plane */
2864 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
2865 setvideoreg(pSiS
, Index_VI_Disp_Y_Buf_Pitch_High
, (CARD8
)(pitch
>> 12));
2866 setvideoreg(pSiS
, Index_VI_Y_Buf_Start_Over
, ((CARD8
)(PSY
>> 24) & 0x03));
2869 /* Set U/V data if using planar formats */
2870 if( (pOverlay
->pixelFormat
== PIXEL_FMT_YV12
) ||
2871 (pOverlay
->pixelFormat
== PIXEL_FMT_I420
) ||
2872 (pOverlay
->pixelFormat
== PIXEL_FMT_NV12
) ||
2873 (pOverlay
->pixelFormat
== PIXEL_FMT_NV21
) ) {
2875 CARD32 PSU
=0, PSV
=0, uvpitch
= pitch
;
2877 PSU
= pOverlay
->PSU
;
2878 PSV
= pOverlay
->PSV
;
2880 if(pSiS
->MergedFB
&& iscrt2
) {
2881 PSU
= pOverlay
->PSU2
;
2882 PSV
= pOverlay
->PSV2
;
2885 if((pOverlay
->pixelFormat
== PIXEL_FMT_YV12
) ||
2886 (pOverlay
->pixelFormat
== PIXEL_FMT_I420
)) {
2891 setvideoreg (pSiS
, Index_VI_Disp_UV_Buf_Pitch_Low
, (CARD8
)uvpitch
);
2892 setvideoregmask (pSiS
, Index_VI_Disp_Y_UV_Buf_Pitch_Middle
, (CARD8
)(uvpitch
>> 4), 0xf0);
2894 /* set U/V start address */
2895 setvideoreg (pSiS
, Index_VI_U_Buf_Start_Low
, (CARD8
)PSU
);
2896 setvideoreg (pSiS
, Index_VI_U_Buf_Start_Middle
,(CARD8
)(PSU
>> 8));
2897 setvideoreg (pSiS
, Index_VI_U_Buf_Start_High
, (CARD8
)(PSU
>> 16));
2899 setvideoreg (pSiS
, Index_VI_V_Buf_Start_Low
, (CARD8
)PSV
);
2900 setvideoreg (pSiS
, Index_VI_V_Buf_Start_Middle
,(CARD8
)(PSV
>> 8));
2901 setvideoreg (pSiS
, Index_VI_V_Buf_Start_High
, (CARD8
)(PSV
>> 16));
2903 /* 315 series overflow bits */
2904 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
2905 setvideoreg (pSiS
, Index_VI_Disp_UV_Buf_Pitch_High
, (CARD8
)(uvpitch
>> 12));
2906 setvideoreg (pSiS
, Index_VI_U_Buf_Start_Over
, ((CARD8
)(PSU
>> 24) & 0x03));
2907 if(pSiS
->sishw_ext
.jChipType
== SIS_661
) {
2908 setvideoregmask (pSiS
, Index_VI_V_Buf_Start_Over
, ((CARD8
)(PSV
>> 24) & 0x03), 0xc3);
2910 setvideoreg (pSiS
, Index_VI_V_Buf_Start_Over
, ((CARD8
)(PSV
>> 24) & 0x03));
2915 /* set scale factor */
2917 if(pSiS
->MergedFB
&& iscrt2
) {
2918 setvideoreg (pSiS
, Index_VI_Hor_Post_Up_Scale_Low
, (CARD8
)(pOverlay
->HUSF2
));
2919 setvideoreg (pSiS
, Index_VI_Hor_Post_Up_Scale_High
,(CARD8
)((pOverlay
->HUSF2
) >> 8));
2920 setvideoreg (pSiS
, Index_VI_Ver_Up_Scale_Low
, (CARD8
)(pOverlay
->VUSF2
));
2921 setvideoreg (pSiS
, Index_VI_Ver_Up_Scale_High
, (CARD8
)((pOverlay
->VUSF2
) >> 8));
2923 setvideoregmask (pSiS
, Index_VI_Scale_Control
, (pOverlay
->IntBit2
<< 3)
2924 |(pOverlay
->wHPre2
), 0x7f);
2927 setvideoreg (pSiS
, Index_VI_Hor_Post_Up_Scale_Low
, (CARD8
)(pOverlay
->HUSF
));
2928 setvideoreg (pSiS
, Index_VI_Hor_Post_Up_Scale_High
,(CARD8
)((pOverlay
->HUSF
) >> 8));
2929 setvideoreg (pSiS
, Index_VI_Ver_Up_Scale_Low
, (CARD8
)(pOverlay
->VUSF
));
2930 setvideoreg (pSiS
, Index_VI_Ver_Up_Scale_High
, (CARD8
)((pOverlay
->VUSF
)>>8));
2932 setvideoregmask (pSiS
, Index_VI_Scale_Control
, (pOverlay
->IntBit
<< 3)
2933 |(pOverlay
->wHPre
), 0x7f);
2938 if((pSiS
->VGAEngine
== SIS_315_VGA
) && (index
)){
2939 /* Trigger register copy for 315/330 series */
2940 /* setvideoreg(pSiS, Index_VI_Control_Misc3, (1 << index)); */
2941 setvideoregmask(pSiS
, Index_VI_Control_Misc3
, (1 << index
), (1 << index
));
2944 /* set destination window position */
2945 setvideoreg(pSiS
, Index_VI_Win_Hor_Disp_Start_Low
, (CARD8
)left
);
2946 setvideoreg(pSiS
, Index_VI_Win_Hor_Disp_End_Low
, (CARD8
)right
);
2947 setvideoreg(pSiS
, Index_VI_Win_Hor_Over
, (CARD8
)h_over
);
2949 setvideoreg(pSiS
, Index_VI_Win_Ver_Disp_Start_Low
, (CARD8
)top
);
2950 setvideoreg(pSiS
, Index_VI_Win_Ver_Disp_End_Low
, (CARD8
)bottom
);
2951 setvideoreg(pSiS
, Index_VI_Win_Ver_Over
, (CARD8
)v_over
);
2953 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, pOverlay
->bobEnable
, 0x1a);
2955 /* Lock the address registers */
2956 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x20);
2959 /* Overlay MUST NOT be switched off while beam is over it */
2961 close_overlay(SISPtr pSiS
, SISPortPrivPtr pPriv
)
2965 if(!(pPriv
->overlayStatus
)) return;
2966 pPriv
->overlayStatus
= FALSE
;
2968 if(pPriv
->displayMode
& (DISPMODE_MIRROR
| DISPMODE_SINGLE2
)) {
2970 /* CRT2: MIRROR or SINGLE2
2971 * 1 overlay: Uses overlay 0
2972 * 2 overlays: Uses Overlay 1 if MIRROR or DUAL HEAD
2973 * Uses Overlay 0 if SINGLE2 and not DUAL HEAD
2976 if(pPriv
->hasTwoOverlays
) {
2978 if((pPriv
->dualHeadMode
) || (pPriv
->displayMode
== DISPMODE_MIRROR
)) {
2979 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x01, 0x01);
2981 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0x01);
2984 } else if(pPriv
->displayMode
== DISPMODE_SINGLE2
) {
2987 if(pPriv
->dualHeadMode
) {
2988 /* Check if overlay already grabbed by other head */
2989 if(!(getsrreg(pSiS
, 0x06) & 0x40)) return;
2992 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0x01);
2996 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x01);
2997 watchdog
= WATCHDOG_DELAY
;
2998 while(vblank_active_CRT2(pSiS
, pPriv
) && --watchdog
);
2999 watchdog
= WATCHDOG_DELAY
;
3000 while((!vblank_active_CRT2(pSiS
, pPriv
)) && --watchdog
);
3001 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
3002 watchdog
= WATCHDOG_DELAY
;
3003 while(vblank_active_CRT2(pSiS
, pPriv
) && --watchdog
);
3004 watchdog
= WATCHDOG_DELAY
;
3005 while((!vblank_active_CRT2(pSiS
, pPriv
)) && --watchdog
);
3013 if(pPriv
->displayMode
& (DISPMODE_SINGLE1
| DISPMODE_MIRROR
)) {
3015 /* CRT1: Always uses overlay 0
3019 if(pPriv
->dualHeadMode
) {
3020 if(!pPriv
->hasTwoOverlays
) {
3021 /* Check if overlay already grabbed by other head */
3022 if(getsrreg(pSiS
, 0x06) & 0x40) return;
3026 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0x05);
3027 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x01);
3028 watchdog
= WATCHDOG_DELAY
;
3029 while(vblank_active_CRT1(pSiS
, pPriv
) && --watchdog
);
3030 watchdog
= WATCHDOG_DELAY
;
3031 while((!vblank_active_CRT1(pSiS
, pPriv
)) && --watchdog
);
3032 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
3033 watchdog
= WATCHDOG_DELAY
;
3034 while(vblank_active_CRT1(pSiS
, pPriv
) && --watchdog
);
3035 watchdog
= WATCHDOG_DELAY
;
3036 while((!vblank_active_CRT1(pSiS
, pPriv
)) && --watchdog
);
3042 SISDisplayVideo(ScrnInfoPtr pScrn
, SISPortPrivPtr pPriv
)
3044 SISPtr pSiS
= SISPTR(pScrn
);
3046 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
3048 short srcPitch
= pPriv
->srcPitch
;
3049 short height
= pPriv
->height
;
3050 unsigned short screenwidth
;
3051 SISOverlayRec overlay
;
3052 int srcOffsetX
=0, srcOffsetY
=0;
3054 int index
= 0, iscrt2
= 0;
3057 unsigned short screen2width
=0;
3058 int srcOffsetX2
=0, srcOffsetY2
=0;
3059 int sx2
=0, sy2
=0, watchdog
;
3062 pPriv
->NoOverlay
= FALSE
;
3064 if(pPriv
->dualHeadMode
) {
3065 if(!pPriv
->hasTwoOverlays
) {
3066 if(pSiS
->SecondHead
) {
3067 if(pSiSEnt
->curxvcrtnum
!= 0) {
3068 if(pPriv
->overlayStatus
) {
3069 close_overlay(pSiS
, pPriv
);
3071 pPriv
->NoOverlay
= TRUE
;
3075 if(pSiSEnt
->curxvcrtnum
!= 1) {
3076 if(pPriv
->overlayStatus
) {
3077 close_overlay(pSiS
, pPriv
);
3079 pPriv
->NoOverlay
= TRUE
;
3087 /* setup dispmode (MIRROR, SINGLEx) */
3088 set_dispmode(pScrn
, pPriv
);
3090 /* Check if overlay is supported with current mode */
3092 if(!pSiS
->MergedFB
) {
3094 if(pPriv
->displayMode
& (DISPMODE_SINGLE1
| DISPMODE_MIRROR
)) {
3095 if(!(pSiS
->MiscFlags
& MISC_CRT1OVERLAY
)) {
3096 if(pPriv
->overlayStatus
) {
3097 close_overlay(pSiS
, pPriv
);
3099 pPriv
->NoOverlay
= TRUE
;
3107 memset(&overlay
, 0, sizeof(overlay
));
3109 overlay
.pixelFormat
= pPriv
->id
;
3110 overlay
.pitch
= overlay
.origPitch
= srcPitch
;
3111 if(pPriv
->usechromakey
) {
3112 overlay
.keyOP
= (pPriv
->insidechromakey
) ? VI_ROP_ChromaKey
: VI_ROP_NotChromaKey
;
3114 overlay
.keyOP
= VI_ROP_DestKey
;
3116 /* overlay.bobEnable = 0x02; */
3117 overlay
.bobEnable
= 0x00; /* Disable BOB de-interlacer */
3120 if(pSiS
->MergedFB
) {
3121 overlay
.DoFirst
= TRUE
;
3122 overlay
.DoSecond
= TRUE
;
3123 overlay
.pitch2
= overlay
.origPitch
;
3124 overlay
.currentmode
= ((SiSMergedDisplayModePtr
)pSiS
->CurrentLayout
.mode
->Private
)->CRT1
;
3125 overlay
.currentmode2
= ((SiSMergedDisplayModePtr
)pSiS
->CurrentLayout
.mode
->Private
)->CRT2
;
3126 overlay
.SCREENheight
= overlay
.currentmode
->VDisplay
;
3127 overlay
.SCREENheight2
= overlay
.currentmode2
->VDisplay
;
3128 screenwidth
= overlay
.currentmode
->HDisplay
;
3129 screen2width
= overlay
.currentmode2
->HDisplay
;
3130 overlay
.dstBox
.x1
= pPriv
->drw_x
- pSiS
->CRT1frameX0
;
3131 overlay
.dstBox
.x2
= overlay
.dstBox
.x1
+ pPriv
->drw_w
;
3132 overlay
.dstBox
.y1
= pPriv
->drw_y
- pSiS
->CRT1frameY0
;
3133 overlay
.dstBox
.y2
= overlay
.dstBox
.y1
+ pPriv
->drw_h
;
3134 overlay
.dstBox2
.x1
= pPriv
->drw_x
- pSiS
->CRT2pScrn
->frameX0
;
3135 overlay
.dstBox2
.x2
= overlay
.dstBox2
.x1
+ pPriv
->drw_w
;
3136 overlay
.dstBox2
.y1
= pPriv
->drw_y
- pSiS
->CRT2pScrn
->frameY0
;
3137 overlay
.dstBox2
.y2
= overlay
.dstBox2
.y1
+ pPriv
->drw_h
;
3138 /* xf86DrvMsg(0, X_INFO, "DV(1): %d %d %d %d | %d %d %d %d\n",
3139 overlay.dstBox.x1,overlay.dstBox.x2,overlay.dstBox.y1,overlay.dstBox.y2,
3140 overlay.dstBox2.x1,overlay.dstBox2.x2,overlay.dstBox2.y1,overlay.dstBox2.y2); */
3143 overlay
.currentmode
= pSiS
->CurrentLayout
.mode
;
3144 overlay
.SCREENheight
= overlay
.currentmode
->VDisplay
;
3145 screenwidth
= overlay
.currentmode
->HDisplay
;
3146 overlay
.dstBox
.x1
= pPriv
->drw_x
- pScrn
->frameX0
;
3147 overlay
.dstBox
.x2
= pPriv
->drw_x
+ pPriv
->drw_w
- pScrn
->frameX0
;
3148 overlay
.dstBox
.y1
= pPriv
->drw_y
- pScrn
->frameY0
;
3149 overlay
.dstBox
.y2
= pPriv
->drw_y
+ pPriv
->drw_h
- pScrn
->frameY0
;
3150 /* xf86DrvMsg(0, X_INFO, "DV(1): %d %d %d %d\n",
3151 overlay.dstBox.x1,overlay.dstBox.x2,overlay.dstBox.y1,overlay.dstBox.y2); */
3156 /* Note: x2/y2 is actually real coordinate + 1 */
3158 if((overlay
.dstBox
.x1
>= overlay
.dstBox
.x2
) ||
3159 (overlay
.dstBox
.y1
>= overlay
.dstBox
.y2
)) {
3161 if(pSiS
->MergedFB
) overlay
.DoFirst
= FALSE
;
3167 if((overlay
.dstBox
.x2
<= 0) || (overlay
.dstBox
.y2
<= 0)) {
3169 if(pSiS
->MergedFB
) overlay
.DoFirst
= FALSE
;
3175 if((overlay
.dstBox
.x1
>= screenwidth
) || (overlay
.dstBox
.y1
>= overlay
.SCREENheight
)) {
3177 if(pSiS
->MergedFB
) overlay
.DoFirst
= FALSE
;
3184 if(pSiS
->MergedFB
) {
3185 /* Check if dotclock is within limits for CRT1 */
3186 if(pPriv
->displayMode
& (DISPMODE_SINGLE1
| DISPMODE_MIRROR
)) {
3187 if(!(pSiS
->MiscFlags
& MISC_CRT1OVERLAY
)) {
3188 overlay
.DoFirst
= FALSE
;
3194 if(overlay
.dstBox
.x1
< 0) {
3195 srcOffsetX
= pPriv
->src_w
* (-overlay
.dstBox
.x1
) / pPriv
->drw_w
;
3196 overlay
.dstBox
.x1
= 0;
3198 if(overlay
.dstBox
.y1
< 0) {
3199 srcOffsetY
= pPriv
->src_h
* (-overlay
.dstBox
.y1
) / pPriv
->drw_h
;
3200 overlay
.dstBox
.y1
= 0;
3204 if(pSiS
->MergedFB
) {
3205 if((overlay
.dstBox2
.x1
>= overlay
.dstBox2
.x2
) ||
3206 (overlay
.dstBox2
.y1
>= overlay
.dstBox2
.y2
))
3207 overlay
.DoSecond
= FALSE
;
3209 if((overlay
.dstBox2
.x2
<= 0) || (overlay
.dstBox2
.y2
<= 0))
3210 overlay
.DoSecond
= FALSE
;
3212 if((overlay
.dstBox2
.x1
>= screen2width
) || (overlay
.dstBox2
.y1
>= overlay
.SCREENheight2
))
3213 overlay
.DoSecond
= FALSE
;
3215 if(overlay
.dstBox2
.x1
< 0) {
3216 srcOffsetX2
= pPriv
->src_w
* (-overlay
.dstBox2
.x1
) / pPriv
->drw_w
;
3217 overlay
.dstBox2
.x1
= 0;
3219 if(overlay
.dstBox2
.y1
< 0) {
3220 srcOffsetY2
= pPriv
->src_h
* (-overlay
.dstBox2
.y1
) / pPriv
->drw_h
;
3221 overlay
.dstBox2
.y1
= 0;
3224 /* If neither overlay is to be displayed, disable them if they are currently enabled */
3225 if((!overlay
.DoFirst
) && (!overlay
.DoSecond
)) {
3226 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0x05);
3227 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x01);
3228 temp
= getvideoreg(pSiS
,Index_VI_Control_Misc0
);
3230 watchdog
= WATCHDOG_DELAY
;
3231 if(pPriv
->hasTwoOverlays
) {
3232 while(vblank_active_CRT1(pSiS
, pPriv
) && --watchdog
);
3233 watchdog
= WATCHDOG_DELAY
;
3234 while((!vblank_active_CRT1(pSiS
, pPriv
)) && --watchdog
);
3236 temp
= getsrreg(pSiS
, 0x06);
3237 if(!(temp
& 0x40)) {
3238 while(vblank_active_CRT1(pSiS
, pPriv
) && --watchdog
);
3239 watchdog
= WATCHDOG_DELAY
;
3240 while((!vblank_active_CRT1(pSiS
, pPriv
)) && --watchdog
);
3242 while(vblank_active_CRT2(pSiS
, pPriv
) && --watchdog
);
3243 watchdog
= WATCHDOG_DELAY
;
3244 while((!vblank_active_CRT2(pSiS
, pPriv
)) && --watchdog
);
3247 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
3249 if(pPriv
->hasTwoOverlays
) {
3250 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x01, 0x01);
3251 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x01);
3252 temp
= getvideoreg(pSiS
,Index_VI_Control_Misc0
);
3254 watchdog
= WATCHDOG_DELAY
;
3255 while(vblank_active_CRT2(pSiS
, pPriv
) && --watchdog
);
3256 watchdog
= WATCHDOG_DELAY
;
3257 while((!vblank_active_CRT2(pSiS
, pPriv
)) && --watchdog
);
3258 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
3261 pPriv
->overlayStatus
= FALSE
;
3269 case PIXEL_FMT_YV12
:
3271 if((!pSiS
->MergedFB
) || (overlay
.DoFirst
)) {
3273 sx
= (pPriv
->src_x
+ srcOffsetX
) & ~7;
3274 sy
= (pPriv
->src_y
+ srcOffsetY
) & ~1;
3275 overlay
.PSY
= pPriv
->bufAddr
[pPriv
->currentBuf
] + sx
+ sy
*srcPitch
;
3276 overlay
.PSV
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
+ ((sx
+ sy
*srcPitch
/2) >> 1);
3277 overlay
.PSU
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
*5/4 + ((sx
+ sy
*srcPitch
/2) >> 1);
3279 overlay
.PSY
+= HEADOFFSET
;
3280 overlay
.PSV
+= HEADOFFSET
;
3281 overlay
.PSU
+= HEADOFFSET
;
3283 overlay
.PSY
>>= pPriv
->shiftValue
;
3284 overlay
.PSV
>>= pPriv
->shiftValue
;
3285 overlay
.PSU
>>= pPriv
->shiftValue
;
3288 if((pSiS
->MergedFB
) && (overlay
.DoSecond
)) {
3289 sx2
= (pPriv
->src_x
+ srcOffsetX2
) & ~7;
3290 sy2
= (pPriv
->src_y
+ srcOffsetY2
) & ~1;
3291 overlay
.PSY2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + sx2
+ sy2
*srcPitch
;
3292 overlay
.PSV2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
+ ((sx2
+ sy2
*srcPitch
/2) >> 1);
3293 overlay
.PSU2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
*5/4 + ((sx2
+ sy2
*srcPitch
/2) >> 1);
3294 overlay
.PSY2
>>= pPriv
->shiftValue
;
3295 overlay
.PSV2
>>= pPriv
->shiftValue
;
3296 overlay
.PSU2
>>= pPriv
->shiftValue
;
3301 case PIXEL_FMT_I420
:
3303 if((!pSiS
->MergedFB
) || (overlay
.DoFirst
)) {
3305 sx
= (pPriv
->src_x
+ srcOffsetX
) & ~7;
3306 sy
= (pPriv
->src_y
+ srcOffsetY
) & ~1;
3307 overlay
.PSY
= pPriv
->bufAddr
[pPriv
->currentBuf
] + sx
+ sy
*srcPitch
;
3308 overlay
.PSV
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
*5/4 + ((sx
+ sy
*srcPitch
/2) >> 1);
3309 overlay
.PSU
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
+ ((sx
+ sy
*srcPitch
/2) >> 1);
3311 overlay
.PSY
+= HEADOFFSET
;
3312 overlay
.PSV
+= HEADOFFSET
;
3313 overlay
.PSU
+= HEADOFFSET
;
3315 overlay
.PSY
>>= pPriv
->shiftValue
;
3316 overlay
.PSV
>>= pPriv
->shiftValue
;
3317 overlay
.PSU
>>= pPriv
->shiftValue
;
3320 if((pSiS
->MergedFB
) && (overlay
.DoSecond
)) {
3321 sx2
= (pPriv
->src_x
+ srcOffsetX2
) & ~7;
3322 sy2
= (pPriv
->src_y
+ srcOffsetY2
) & ~1;
3323 overlay
.PSY2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + sx2
+ sy2
*srcPitch
;
3324 overlay
.PSV2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
*5/4 + ((sx2
+ sy2
*srcPitch
/2) >> 1);
3325 overlay
.PSU2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
+ ((sx2
+ sy2
*srcPitch
/2) >> 1);
3326 overlay
.PSY2
>>= pPriv
->shiftValue
;
3327 overlay
.PSV2
>>= pPriv
->shiftValue
;
3328 overlay
.PSU2
>>= pPriv
->shiftValue
;
3333 case PIXEL_FMT_NV12
:
3334 case PIXEL_FMT_NV21
:
3336 if((!pSiS
->MergedFB
) || (overlay
.DoFirst
)) {
3338 sx
= (pPriv
->src_x
+ srcOffsetX
) & ~7;
3339 sy
= (pPriv
->src_y
+ srcOffsetY
) & ~1;
3340 overlay
.PSY
= pPriv
->bufAddr
[pPriv
->currentBuf
] + sx
+ sy
*srcPitch
;
3341 overlay
.PSV
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
+ ((sx
+ sy
*srcPitch
/2) >> 1);
3343 overlay
.PSY
+= HEADOFFSET
;
3344 overlay
.PSV
+= HEADOFFSET
;
3346 overlay
.PSY
>>= pPriv
->shiftValue
;
3347 overlay
.PSV
>>= pPriv
->shiftValue
;
3348 overlay
.PSU
= overlay
.PSV
;
3351 if((pSiS
->MergedFB
) && (overlay
.DoSecond
)) {
3352 sx2
= (pPriv
->src_x
+ srcOffsetX2
) & ~7;
3353 sy2
= (pPriv
->src_y
+ srcOffsetY2
) & ~1;
3354 overlay
.PSY2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + sx2
+ sy2
*srcPitch
;
3355 overlay
.PSV2
= pPriv
->bufAddr
[pPriv
->currentBuf
] + height
*srcPitch
+ ((sx2
+ sy2
*srcPitch
/2) >> 1);
3356 overlay
.PSY2
>>= pPriv
->shiftValue
;
3357 overlay
.PSV2
>>= pPriv
->shiftValue
;
3358 overlay
.PSU2
= overlay
.PSV2
;
3363 case PIXEL_FMT_YUY2
:
3364 case PIXEL_FMT_UYVY
:
3365 case PIXEL_FMT_YVYU
:
3366 case PIXEL_FMT_RGB6
:
3367 case PIXEL_FMT_RGB5
:
3370 if((!pSiS
->MergedFB
) || (overlay
.DoFirst
)) {
3372 sx
= (pPriv
->src_x
+ srcOffsetX
) & ~1;
3373 sy
= (pPriv
->src_y
+ srcOffsetY
);
3374 overlay
.PSY
= (pPriv
->bufAddr
[pPriv
->currentBuf
] + sx
*2 + sy
*srcPitch
);
3376 overlay
.PSY
+= HEADOFFSET
;
3378 overlay
.PSY
>>= pPriv
->shiftValue
;
3381 if((pSiS
->MergedFB
) && (overlay
.DoSecond
)) {
3382 sx2
= (pPriv
->src_x
+ srcOffsetX2
) & ~1;
3383 sy2
= (pPriv
->src_y
+ srcOffsetY2
);
3384 overlay
.PSY2
= (pPriv
->bufAddr
[pPriv
->currentBuf
] + sx2
*2 + sy2
*srcPitch
);
3385 overlay
.PSY2
>>= pPriv
->shiftValue
;
3391 /* Some clipping checks */
3393 if((!pSiS
->MergedFB
) || (overlay
.DoFirst
)) {
3395 overlay
.srcW
= pPriv
->src_w
- (sx
- pPriv
->src_x
);
3396 overlay
.srcH
= pPriv
->src_h
- (sy
- pPriv
->src_y
);
3397 if( (pPriv
->oldx1
!= overlay
.dstBox
.x1
) ||
3398 (pPriv
->oldx2
!= overlay
.dstBox
.x2
) ||
3399 (pPriv
->oldy1
!= overlay
.dstBox
.y1
) ||
3400 (pPriv
->oldy2
!= overlay
.dstBox
.y2
) ) {
3401 pPriv
->mustwait
= 1;
3402 pPriv
->oldx1
= overlay
.dstBox
.x1
; pPriv
->oldx2
= overlay
.dstBox
.x2
;
3403 pPriv
->oldy1
= overlay
.dstBox
.y1
; pPriv
->oldy2
= overlay
.dstBox
.y2
;
3408 if((pSiS
->MergedFB
) && (overlay
.DoSecond
)) {
3409 overlay
.srcW2
= pPriv
->src_w
- (sx2
- pPriv
->src_x
);
3410 overlay
.srcH2
= pPriv
->src_h
- (sy2
- pPriv
->src_y
);
3411 if( (pPriv
->oldx1_2
!= overlay
.dstBox2
.x1
) ||
3412 (pPriv
->oldx2_2
!= overlay
.dstBox2
.x2
) ||
3413 (pPriv
->oldy1_2
!= overlay
.dstBox2
.y1
) ||
3414 (pPriv
->oldy2_2
!= overlay
.dstBox2
.y2
) ) {
3415 pPriv
->mustwait
= 1;
3416 pPriv
->oldx1_2
= overlay
.dstBox2
.x1
; pPriv
->oldx2_2
= overlay
.dstBox2
.x2
;
3417 pPriv
->oldy1_2
= overlay
.dstBox2
.y1
; pPriv
->oldy2_2
= overlay
.dstBox2
.y2
;
3423 /* Disable an overlay if it is not to be displayed (but enabled currently) */
3424 if((pSiS
->MergedFB
) && (pPriv
->hasTwoOverlays
)) {
3425 if(!overlay
.DoFirst
) {
3426 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x00, 0x05);
3427 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x01);
3428 temp
= getvideoreg(pSiS
,Index_VI_Control_Misc0
);
3430 watchdog
= WATCHDOG_DELAY
;
3431 while(vblank_active_CRT1(pSiS
, pPriv
) && --watchdog
);
3432 watchdog
= WATCHDOG_DELAY
;
3433 while((!vblank_active_CRT1(pSiS
, pPriv
)) && --watchdog
);
3434 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
3436 } else if(!overlay
.DoSecond
) {
3437 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, 0x01, 0x01);
3438 setvideoregmask(pSiS
, Index_VI_Control_Misc1
, 0x00, 0x01);
3439 temp
= getvideoreg(pSiS
,Index_VI_Control_Misc0
);
3441 watchdog
= WATCHDOG_DELAY
;
3442 while(vblank_active_CRT2(pSiS
, pPriv
) && --watchdog
);
3443 watchdog
= WATCHDOG_DELAY
;
3444 while((!vblank_active_CRT2(pSiS
, pPriv
)) && --watchdog
);
3445 setvideoregmask(pSiS
, Index_VI_Control_Misc0
, 0x00, 0x02);
3452 if(pPriv
->displayMode
& DISPMODE_SINGLE2
) {
3453 if(pPriv
->hasTwoOverlays
) { /* We have 2 overlays: */
3454 if(pPriv
->dualHeadMode
) {
3455 /* Dual head: We use overlay 2 for CRT2 */
3456 index
= 1; iscrt2
= 1;
3458 /* Single head: We use overlay 1 for CRT2 */
3459 index
= 0; iscrt2
= 1;
3461 } else { /* We have 1 overlay */
3462 /* We use that only overlay for CRT2 */
3463 index
= 0; iscrt2
= 1;
3465 overlay
.VBlankActiveFunc
= vblank_active_CRT2
;
3467 if(!pPriv
->hasTwoOverlays
) {
3468 if((pSiS
->MergedFB
) && (!overlay
.DoSecond
)) {
3469 index
= 0; iscrt2
= 0;
3470 overlay
.VBlankActiveFunc
= vblank_active_CRT1
;
3471 pPriv
->displayMode
= DISPMODE_SINGLE1
;
3476 index
= 0; iscrt2
= 0;
3477 overlay
.VBlankActiveFunc
= vblank_active_CRT1
;
3479 if((pSiS
->MergedFB
) && (!overlay
.DoFirst
)) {
3480 if(pPriv
->hasTwoOverlays
) index
= 1;
3482 overlay
.VBlankActiveFunc
= vblank_active_CRT2
;
3483 if(!pPriv
->hasTwoOverlays
) {
3484 pPriv
->displayMode
= DISPMODE_SINGLE2
;
3490 /* set display mode SR06,32 (CRT1, CRT2 or mirror) */
3491 set_disptype_regs(pScrn
, pPriv
);
3493 /* set (not only calc) merge line buffer */
3495 if(!pSiS
->MergedFB
) {
3497 merge_line_buf(pSiS
, pPriv
, (overlay
.srcW
> pPriv
->linebufMergeLimit
), overlay
.srcW
,
3498 pPriv
->linebufMergeLimit
);
3501 Bool temp1
= FALSE
, temp2
= FALSE
;
3502 if(overlay
.DoFirst
) {
3503 if(overlay
.srcW
> pPriv
->linebufMergeLimit
) temp1
= TRUE
;
3505 if(overlay
.DoSecond
) {
3506 if(overlay
.srcW2
> pPriv
->linebufMergeLimit
) temp2
= TRUE
;
3508 merge_line_buf_mfb(pSiS
, pPriv
, temp1
, temp2
, overlay
.srcW
, overlay
.srcW2
, pPriv
->linebufMergeLimit
);
3512 /* calculate (not set!) line buffer length */
3514 if((!pSiS
->MergedFB
) || (overlay
.DoFirst
))
3516 set_line_buf_size_1(&overlay
);
3518 if((pSiS
->MergedFB
) && (overlay
.DoSecond
))
3519 set_line_buf_size_2(&overlay
);
3522 /* Do the following in a loop for CRT1 and CRT2 ----------------- */
3525 /* calculate (not set!) scale factor */
3527 if(pSiS
->MergedFB
&& iscrt2
)
3528 calc_scale_factor_2(&overlay
, pScrn
, pPriv
, index
, iscrt2
);
3531 calc_scale_factor(&overlay
, pScrn
, pPriv
, index
, iscrt2
);
3533 /* Select overlay 1 (used for CRT1/or CRT2) or overlay 2 (used for CRT2) */
3534 setvideoregmask(pSiS
, Index_VI_Control_Misc2
, index
, 0x01);
3537 set_format(pSiS
, &overlay
);
3540 set_colorkey(pSiS
, pPriv
->colorKey
);
3542 if(pPriv
->usechromakey
) {
3543 /* Select chroma key format (300 series only) */
3544 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
3545 setvideoregmask(pSiS
, Index_VI_Control_Misc0
,
3546 (pPriv
->yuvchromakey
? 0x40 : 0x00), 0x40);
3548 set_chromakey(pSiS
, pPriv
->chromamin
, pPriv
->chromamax
);
3551 /* set brightness, contrast, hue, saturation */
3552 set_brightness(pSiS
, pPriv
->brightness
);
3553 set_contrast(pSiS
, pPriv
->contrast
);
3554 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
3555 set_hue(pSiS
, pPriv
->hue
);
3556 set_saturation(pSiS
, pPriv
->saturation
);
3559 if(pPriv
->dualHeadMode
) {
3561 if(!pSiS
->SecondHead
) {
3562 if(pPriv
->updatetvxpos
) {
3563 SiS_SetTVxposoffset(pScrn
, pPriv
->tvxpos
);
3564 pPriv
->updatetvxpos
= FALSE
;
3566 if(pPriv
->updatetvypos
) {
3567 SiS_SetTVyposoffset(pScrn
, pPriv
->tvypos
);
3568 pPriv
->updatetvypos
= FALSE
;
3573 if(pPriv
->updatetvxpos
) {
3574 SiS_SetTVxposoffset(pScrn
, pPriv
->tvxpos
);
3575 pPriv
->updatetvxpos
= FALSE
;
3577 if(pPriv
->updatetvypos
) {
3578 SiS_SetTVyposoffset(pScrn
, pPriv
->tvypos
);
3579 pPriv
->updatetvypos
= FALSE
;
3583 /* enable/disable graphics display around overlay
3584 * (Since disabled overlays don't get treated in this
3585 * loop, we omit respective checks here)
3588 if(!iscrt2
) set_disablegfx(pSiS
, pPriv
->disablegfx
, &overlay
);
3589 else if(!pPriv
->hasTwoOverlays
) {
3590 set_disablegfx(pSiS
, FALSE
, &overlay
);
3592 set_disablegfxlr(pSiS
, pPriv
->disablegfxlr
, &overlay
);
3598 /* set overlay parameters */
3599 set_overlay(pSiS
, &overlay
, pPriv
, index
, iscrt2
);
3601 if((pSiS
->VGAEngine
== SIS_315_VGA
) && !index
) {
3602 /* Trigger register copy for 315 series */
3603 setvideoregmask(pSiS
, Index_VI_Control_Misc3
, (1 << index
), (1 << index
));
3606 /* enable overlay */
3607 setvideoregmask (pSiS
, Index_VI_Control_Misc0
, 0x02, 0x02);
3610 if(pPriv
->displayMode
& DISPMODE_MIRROR
&&
3612 pPriv
->hasTwoOverlays
) {
3614 if((!pSiS
->MergedFB
) || overlay
.DoSecond
) {
3616 index
= 1; iscrt2
= 1;
3617 overlay
.VBlankActiveFunc
= vblank_active_CRT2
;
3624 pPriv
->mustwait
= 0;
3625 pPriv
->overlayStatus
= TRUE
;
3629 SISAllocateOverlayMemory(
3635 FBLinearPtr new_linear
;
3638 if(linear
->size
>= size
)
3641 if(xf86ResizeOffscreenLinear(linear
, size
))
3644 xf86FreeOffscreenLinear(linear
);
3647 pScreen
= screenInfo
.screens
[pScrn
->scrnIndex
];
3649 new_linear
= xf86AllocateOffscreenLinear(pScreen
, size
, 8,
3655 xf86QueryLargestOffscreenLinear(pScreen
, &max_size
, 8,
3658 if(max_size
< size
) return NULL
;
3660 xf86PurgeUnlockedOffscreenAreas(pScreen
);
3661 new_linear
= xf86AllocateOffscreenLinear(pScreen
, size
, 8,
3665 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
3666 "Xv: Failed to allocate %dK of video memory\n", size
/1024);
3669 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
3670 "Xv: Allocated %dK of video memory\n", size
/1024);
3677 SISFreeOverlayMemory(ScrnInfoPtr pScrn
)
3679 SISPortPrivPtr pPriv
= GET_PORT_PRIVATE(pScrn
);
3682 xf86FreeOffscreenLinear(pPriv
->linear
);
3683 pPriv
->linear
= NULL
;
3688 SISStopVideo(ScrnInfoPtr pScrn
, pointer data
, Bool shutdown
)
3690 SISPortPrivPtr pPriv
= (SISPortPrivPtr
)data
;
3691 SISPtr pSiS
= SISPTR(pScrn
);
3693 if(pPriv
->grabbedByV4L
) return;
3695 REGION_EMPTY(pScrn
->pScreen
, &pPriv
->clip
);
3698 if(pPriv
->videoStatus
& CLIENT_VIDEO_ON
) {
3699 close_overlay(pSiS
, pPriv
);
3700 pPriv
->mustwait
= 1;
3702 SISFreeOverlayMemory(pScrn
);
3703 pPriv
->videoStatus
= 0;
3704 pSiS
->VideoTimerCallback
= NULL
;
3706 if(pPriv
->videoStatus
& CLIENT_VIDEO_ON
) {
3707 pPriv
->videoStatus
= OFF_TIMER
| CLIENT_VIDEO_ON
;
3708 pPriv
->offTime
= currentTime
.milliseconds
+ OFF_DELAY
;
3709 pSiS
->VideoTimerCallback
= SISVideoTimerCallback
;
3717 short src_x
, short src_y
,
3718 short drw_x
, short drw_y
,
3719 short src_w
, short src_h
,
3720 short drw_w
, short drw_h
,
3721 int id
, unsigned char* buf
,
3722 short width
, short height
,
3724 RegionPtr clipBoxes
, pointer data
3726 SISPtr pSiS
= SISPTR(pScrn
);
3727 SISPortPrivPtr pPriv
= (SISPortPrivPtr
)data
;
3730 int depth
= pSiS
->CurrentLayout
.bitsPerPixel
>> 3;
3731 int myreds
[] = { 0x000000ff, 0x0000f800, 0, 0x00ff0000 };
3735 return(SiSHandleSiSDirectCommand(pScrn
, pPriv
, (sisdirectcommand
*)buf
));
3739 if(pPriv
->grabbedByV4L
) return Success
;
3741 pPriv
->drw_x
= drw_x
;
3742 pPriv
->drw_y
= drw_y
;
3743 pPriv
->drw_w
= drw_w
;
3744 pPriv
->drw_h
= drw_h
;
3745 pPriv
->src_x
= src_x
;
3746 pPriv
->src_y
= src_y
;
3747 pPriv
->src_w
= src_w
;
3748 pPriv
->src_h
= src_h
;
3750 pPriv
->height
= height
;
3753 1. YU12: 3 planes: H V
3754 Y sample period 1 1 (8 bit per pixel)
3755 V sample period 2 2 (8 bit per pixel, subsampled)
3756 U sample period 2 2 (8 bit per pixel, subsampled)
3758 Y plane is fully sampled (width*height), U and V planes
3759 are sampled in 2x2 blocks, hence a group of 4 pixels requires
3760 4 + 1 + 1 = 6 bytes. The data is planar, ie in single planes
3762 2. UYVY: 3 planes: H V
3763 Y sample period 1 1 (8 bit per pixel)
3764 V sample period 2 1 (8 bit per pixel, subsampled)
3765 U sample period 2 1 (8 bit per pixel, subsampled)
3766 Y plane is fully sampled (width*height), U and V planes
3767 are sampled in 2x1 blocks, hence a group of 4 pixels requires
3768 4 + 2 + 2 = 8 bytes. The data is bit packed, there are no separate
3770 Bit order: U0 Y0 V0 Y1 U2 Y2 V2 Y3 ...
3771 3. I420: Like YU12, but planes U and V are in reverse order.
3772 4. YUY2: Like UYVY, but order is
3773 Y0 U0 Y1 V0 Y2 U2 Y3 V2 ...
3774 5. YVYU: Like YUY2, but order is
3775 Y0 V0 Y1 U0 Y2 V2 Y3 U2 ...
3779 case PIXEL_FMT_YV12
:
3780 case PIXEL_FMT_I420
:
3781 case PIXEL_FMT_NV12
:
3782 case PIXEL_FMT_NV21
:
3783 pPriv
->srcPitch
= (width
+ 7) & ~7;
3784 /* Size = width * height * 3 / 2 */
3785 totalSize
= (pPriv
->srcPitch
* height
* 3) >> 1; /* Verified */
3787 case PIXEL_FMT_YUY2
:
3788 case PIXEL_FMT_UYVY
:
3789 case PIXEL_FMT_YVYU
:
3790 case PIXEL_FMT_RGB6
:
3791 case PIXEL_FMT_RGB5
:
3793 pPriv
->srcPitch
= ((width
<< 1) + 3) & ~3; /* Verified */
3794 /* Size = width * 2 * height */
3795 totalSize
= pPriv
->srcPitch
* height
;
3798 /* make it a multiple of 16 to simplify to copy loop */
3802 /* allocate memory (we do doublebuffering) */
3803 if(!(pPriv
->linear
= SISAllocateOverlayMemory(pScrn
, pPriv
->linear
,
3807 /* fixup pointers */
3808 pPriv
->bufAddr
[0] = (pPriv
->linear
->offset
* depth
);
3809 pPriv
->bufAddr
[1] = pPriv
->bufAddr
[0] + totalSize
;
3812 if((pSiS
->XvUseMemcpy
) || (totalSize
< 16)) {
3813 memcpy(pSiS
->FbBase
+ pPriv
->bufAddr
[pPriv
->currentBuf
], buf
, totalSize
);
3816 CARD32
*src
= (CARD32
*)buf
;
3817 CARD32
*dest
= (CARD32
*)(pSiS
->FbBase
+ pPriv
->bufAddr
[pPriv
->currentBuf
]);
3818 for(i
= 0; i
< (totalSize
/16); i
++) {
3826 SISDisplayVideo(pScrn
, pPriv
);
3828 /* update cliplist */
3829 if(pPriv
->autopaintColorKey
&&
3830 (pPriv
->grabbedByV4L
||
3831 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0)
3832 (!RegionsEqual(&pPriv
->clip
, clipBoxes
)) ||
3834 (!REGION_EQUAL(pScrn
->pScreen
, &pPriv
->clip
, clipBoxes
)) ||
3836 (pPriv
->PrevOverlay
!= pPriv
->NoOverlay
))) {
3837 /* We always paint the colorkey for V4L */
3838 if(!pPriv
->grabbedByV4L
) {
3839 REGION_COPY(pScrn
->pScreen
, &pPriv
->clip
, clipBoxes
);
3842 pPriv
->PrevOverlay
= pPriv
->NoOverlay
;
3843 if((pPriv
->NoOverlay
) && (!pSiS
->NoAccel
)) {
3844 XAAFillMono8x8PatternRects(pScrn
, myreds
[depth
-1], 0x000000, GXcopy
, ~0,
3845 REGION_NUM_RECTS(clipBoxes
),
3846 REGION_RECTS(clipBoxes
),
3847 0x00422418, 0x18244200, 0, 0);
3849 if(!pSiS
->disablecolorkeycurrent
) {
3850 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
3851 XAAFillSolidRects(pScrn
, pPriv
->colorKey
, GXcopy
, ~0,
3852 REGION_NUM_RECTS(clipBoxes
),
3853 REGION_RECTS(clipBoxes
));
3855 xf86XVFillKeyHelper(pScrn
->pScreen
, pPriv
->colorKey
, clipBoxes
);
3862 pPriv
->currentBuf
^= 1;
3864 pPriv
->videoStatus
= CLIENT_VIDEO_ON
;
3866 pSiS
->VideoTimerCallback
= SISVideoTimerCallback
;
3872 SISQueryImageAttributes(
3875 unsigned short *w
, unsigned short *h
,
3876 int *pitches
, int *offsets
3878 int pitchY
, pitchUV
;
3879 int size
, sizeY
, sizeUV
;
3881 if(*w
< IMAGE_MIN_WIDTH
) *w
= IMAGE_MIN_WIDTH
;
3882 if(*h
< IMAGE_MIN_HEIGHT
) *h
= IMAGE_MIN_HEIGHT
;
3884 if(*w
> DummyEncoding
.width
) *w
= DummyEncoding
.width
;
3885 if(*h
> DummyEncoding
.height
) *h
= DummyEncoding
.height
;
3888 case PIXEL_FMT_YV12
:
3889 case PIXEL_FMT_I420
:
3895 pitches
[0] = pitchY
;
3896 pitches
[1] = pitches
[2] = pitchUV
;
3898 sizeY
= pitchY
* (*h
);
3899 sizeUV
= pitchUV
* ((*h
) >> 1);
3903 offsets
[2] = sizeY
+ sizeUV
;
3905 size
= sizeY
+ (sizeUV
<< 1);
3907 case PIXEL_FMT_NV12
:
3908 case PIXEL_FMT_NV21
:
3914 pitches
[0] = pitchY
;
3915 pitches
[1] = pitchUV
;
3917 sizeY
= pitchY
* (*h
);
3918 sizeUV
= pitchUV
* ((*h
) >> 1);
3923 size
= sizeY
+ (sizeUV
<< 1);
3925 case PIXEL_FMT_YUY2
:
3926 case PIXEL_FMT_UYVY
:
3927 case PIXEL_FMT_YVYU
:
3928 case PIXEL_FMT_RGB6
:
3929 case PIXEL_FMT_RGB5
:
3933 if(pitches
) pitches
[0] = pitchY
;
3934 if(offsets
) offsets
[0] = 0;
3935 size
= pitchY
* (*h
);
3943 SISVideoTimerCallback(ScrnInfoPtr pScrn
, Time now
)
3945 SISPtr pSiS
= SISPTR(pScrn
);
3946 SISPortPrivPtr pPriv
= NULL
;
3947 unsigned char sridx
, cridx
;
3949 pSiS
->VideoTimerCallback
= NULL
;
3951 if(!pScrn
->vtSema
) return;
3954 pPriv
= GET_PORT_PRIVATE(pScrn
);
3955 if(!pPriv
->videoStatus
)
3960 if(pPriv
->videoStatus
& TIMER_MASK
) {
3961 UpdateCurrentTime();
3962 if(pPriv
->offTime
< currentTime
.milliseconds
) {
3963 if(pPriv
->videoStatus
& OFF_TIMER
) {
3964 /* Turn off the overlay */
3965 sridx
= inSISREG(SISSR
); cridx
= inSISREG(SISCR
);
3966 close_overlay(pSiS
, pPriv
);
3967 outSISREG(SISSR
, sridx
); outSISREG(SISCR
, cridx
);
3968 pPriv
->mustwait
= 1;
3969 pPriv
->videoStatus
= FREE_TIMER
;
3970 pPriv
->freeTime
= currentTime
.milliseconds
+ FREE_DELAY
;
3971 pSiS
->VideoTimerCallback
= SISVideoTimerCallback
;
3972 } else if(pPriv
->videoStatus
& FREE_TIMER
) {
3973 SISFreeOverlayMemory(pScrn
);
3974 pPriv
->mustwait
= 1;
3975 pPriv
->videoStatus
= 0;
3978 pSiS
->VideoTimerCallback
= SISVideoTimerCallback
;
3983 /* Offscreen surface stuff */
3991 XF86SurfacePtr surface
3994 SISPtr pSiS
= SISPTR(pScrn
);
3995 SISPortPrivPtr pPriv
= GET_PORT_PRIVATE(pScrn
);
3999 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "Xv: SISAllocSurface called\n");
4002 if((w
< IMAGE_MIN_WIDTH
) || (h
< IMAGE_MIN_HEIGHT
))
4004 if((w
> DummyEncoding
.width
) || (h
> DummyEncoding
.height
))
4007 if(pPriv
->grabbedByV4L
)
4010 depth
= pSiS
->CurrentLayout
.bitsPerPixel
>> 3;
4012 pPriv
->pitch
= ((w
<< 1) + 63) & ~63; /* Only packed pixel modes supported */
4013 size
= h
* pPriv
->pitch
; /* / depth; - Why? */
4014 pPriv
->linear
= SISAllocateOverlayMemory(pScrn
, pPriv
->linear
, size
);
4018 pPriv
->offset
= pPriv
->linear
->offset
* depth
;
4021 surface
->height
= h
;
4022 surface
->pScrn
= pScrn
;
4024 surface
->pitches
= &pPriv
->pitch
;
4025 surface
->offsets
= &pPriv
->offset
;
4026 surface
->devPrivate
.ptr
= (pointer
)pPriv
;
4028 close_overlay(pSiS
, pPriv
);
4029 pPriv
->videoStatus
= 0;
4030 REGION_EMPTY(pScrn
->pScreen
, &pPriv
->clip
);
4031 pSiS
->VideoTimerCallback
= NULL
;
4032 pPriv
->grabbedByV4L
= TRUE
;
4037 SISStopSurface (XF86SurfacePtr surface
)
4039 SISPortPrivPtr pPriv
= (SISPortPrivPtr
)(surface
->devPrivate
.ptr
);
4040 SISPtr pSiS
= SISPTR(surface
->pScrn
);
4042 if(pPriv
->grabbedByV4L
&& pPriv
->videoStatus
) {
4043 close_overlay(pSiS
, pPriv
);
4044 pPriv
->mustwait
= 1;
4045 pPriv
->videoStatus
= 0;
4051 SISFreeSurface (XF86SurfacePtr surface
)
4053 SISPortPrivPtr pPriv
= (SISPortPrivPtr
)(surface
->devPrivate
.ptr
);
4055 if(pPriv
->grabbedByV4L
) {
4056 SISStopSurface(surface
);
4057 SISFreeOverlayMemory(surface
->pScrn
);
4058 pPriv
->grabbedByV4L
= FALSE
;
4064 SISGetSurfaceAttribute (
4070 SISPortPrivPtr pPriv
= GET_PORT_PRIVATE(pScrn
);
4072 return SISGetPortAttribute(pScrn
, attribute
, value
, (pointer
)pPriv
);
4076 SISSetSurfaceAttribute(
4082 SISPortPrivPtr pPriv
= GET_PORT_PRIVATE(pScrn
);;
4084 return SISSetPortAttribute(pScrn
, attribute
, value
, (pointer
)pPriv
);
4089 XF86SurfacePtr surface
,
4090 short src_x
, short src_y
,
4091 short drw_x
, short drw_y
,
4092 short src_w
, short src_h
,
4093 short drw_w
, short drw_h
,
4097 ScrnInfoPtr pScrn
= surface
->pScrn
;
4098 SISPtr pSiS
= SISPTR(pScrn
);
4099 SISPortPrivPtr pPriv
= (SISPortPrivPtr
)(surface
->devPrivate
.ptr
);
4100 int myreds
[] = { 0x000000ff, 0x0000f800, 0, 0x00ff0000 };
4103 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "Xv: DisplaySurface called\n");
4106 if(!pPriv
->grabbedByV4L
) return Success
;
4108 pPriv
->drw_x
= drw_x
;
4109 pPriv
->drw_y
= drw_y
;
4110 pPriv
->drw_w
= drw_w
;
4111 pPriv
->drw_h
= drw_h
;
4112 pPriv
->src_x
= src_x
;
4113 pPriv
->src_y
= src_y
;
4114 pPriv
->src_w
= src_w
;
4115 pPriv
->src_h
= src_h
;
4116 pPriv
->id
= surface
->id
;
4117 pPriv
->height
= surface
->height
;
4118 pPriv
->bufAddr
[0] = surface
->offsets
[0];
4119 pPriv
->currentBuf
= 0;
4120 pPriv
->srcPitch
= surface
->pitches
[0];
4122 SISDisplayVideo(pScrn
, pPriv
);
4124 if(pPriv
->autopaintColorKey
) {
4125 if((pPriv
->NoOverlay
) && (!(pSiS
->NoAccel
))) {
4126 XAAFillMono8x8PatternRects(pScrn
,
4127 myreds
[(pSiS
->CurrentLayout
.bitsPerPixel
>> 3) - 1],
4128 0x000000, GXcopy
, ~0,
4129 REGION_NUM_RECTS(clipBoxes
),
4130 REGION_RECTS(clipBoxes
),
4131 0x00422418, 0x18244200, 0, 0);
4134 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0)
4135 XAAFillSolidRects(pScrn
, pPriv
->colorKey
, GXcopy
, ~0,
4136 REGION_NUM_RECTS(clipBoxes
),
4137 REGION_RECTS(clipBoxes
));
4139 xf86XVFillKeyHelper(pScrn
->pScreen
, pPriv
->colorKey
, clipBoxes
);
4144 pPriv
->videoStatus
= CLIENT_VIDEO_ON
;
4149 #define NUMOFFSCRIMAGES_300 4
4150 #define NUMOFFSCRIMAGES_315 5
4152 static XF86OffscreenImageRec SISOffscreenImages
[NUMOFFSCRIMAGES_315
] =
4155 &SISImages
[0], /* YUV2 */
4156 VIDEO_OVERLAID_IMAGES
| VIDEO_CLIP_TO_VIEWPORT
,
4161 SISGetSurfaceAttribute
,
4162 SISSetSurfaceAttribute
,
4163 0, 0, /* Rest will be filled in */
4168 &SISImages
[2], /* UYVY */
4169 VIDEO_OVERLAID_IMAGES
| VIDEO_CLIP_TO_VIEWPORT
,
4174 SISGetSurfaceAttribute
,
4175 SISSetSurfaceAttribute
,
4176 0, 0, /* Rest will be filled in */
4182 &SISImages
[4], /* RV15 */
4183 VIDEO_OVERLAID_IMAGES
| VIDEO_CLIP_TO_VIEWPORT
,
4188 SISGetSurfaceAttribute
,
4189 SISSetSurfaceAttribute
,
4190 0, 0, /* Rest will be filled in */
4195 &SISImages
[5], /* RV16 */
4196 VIDEO_OVERLAID_IMAGES
| VIDEO_CLIP_TO_VIEWPORT
,
4201 SISGetSurfaceAttribute
,
4202 SISSetSurfaceAttribute
,
4203 0, 0, /* Rest will be filled in */
4208 &SISImages
[6], /* YVYU */
4209 VIDEO_OVERLAID_IMAGES
| VIDEO_CLIP_TO_VIEWPORT
,
4214 SISGetSurfaceAttribute
,
4215 SISSetSurfaceAttribute
,
4216 0, 0, /* Rest will be filled in */
4223 SISInitOffscreenImages(ScreenPtr pScreen
)
4225 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
4226 SISPtr pSiS
= SISPTR(pScrn
);
4227 SISPortPrivPtr pPriv
= GET_PORT_PRIVATE(pScrn
);
4230 if(pSiS
->VGAEngine
== SIS_300_VGA
) num
= NUMOFFSCRIMAGES_300
;
4231 else num
= NUMOFFSCRIMAGES_315
;
4233 for(i
= 0; i
<= num
; i
++) {
4234 SISOffscreenImages
[i
].max_width
= DummyEncoding
.width
;
4235 SISOffscreenImages
[i
].max_height
= DummyEncoding
.height
;
4236 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
4237 SISOffscreenImages
[i
].num_attributes
= NUM_ATTRIBUTES_300
;
4238 SISOffscreenImages
[i
].attributes
= &SISAttributes_300
[0];
4240 if(pPriv
->hasTwoOverlays
) {
4241 SISOffscreenImages
[i
].num_attributes
= NUM_ATTRIBUTES_315
;
4243 SISOffscreenImages
[i
].num_attributes
= NUM_ATTRIBUTES_315
- 1;
4245 SISOffscreenImages
[i
].attributes
= &SISAttributes_315
[0];
4248 xf86XVRegisterOffscreenImages(pScreen
, SISOffscreenImages
, num
);
4251 #ifdef NOT_YET_IMPLEMENTED /* ----------- TW: FOR FUTURE USE -------------------- */
4253 /* Set alpha - does not work */
4255 set_alpha(SISPtr pSiS
, CARD8 alpha
)
4257 setvideoregmask(pSiS
, Index_VI_Key_Overlay_OP
, ((alpha
& 0x0f) << 4), 0xf0);
4260 /* Set SubPicture Start Address (yet unused) */
4262 set_subpict_start_offset(SISPtr pSiS
, SISOverlayPtr pOverlay
, int index
)
4267 temp
= pOverlay
->SubPictAddr
>> 4; /* 630 <-> 315 shiftValue? */
4269 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Start_Low
, temp
& 0xFF);
4270 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Start_Middle
, (temp
>>8) & 0xFF);
4271 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Start_High
, (temp
>>16) & 0x3F);
4272 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
4273 setvideoreg(pSiS
,Index_VI_SubPict_Start_Over
, (temp
>>22) & 0x01);
4274 /* Submit SubPict offset ? */
4275 /* data=getvideoreg(pSiS,Index_VI_Control_Misc3); */
4276 setvideoreg(pSiS
,Index_VI_Control_Misc3
, (1 << index
) | 0x04);
4280 /* Set SubPicture Pitch (yet unused) */
4282 set_subpict_pitch(SISPtr pSiS
, SISOverlayPtr pOverlay
, int index
)
4287 temp
= pOverlay
->SubPictPitch
>> 4; /* 630 <-> 315 shiftValue? */
4289 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Pitch
, temp
& 0xFF);
4290 if(pSiS
->VGAEngine
== SIS_315_VGA
) {
4291 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Pitch_High
, (temp
>>8) & 0xFF);
4292 /* Submit SubPict pitch ? */
4293 /* data=getvideoreg(pSiS,Index_VI_Control_Misc3); */
4294 setvideoreg(pSiS
,Index_VI_Control_Misc3
, (1 << index
) | 0x04);
4298 /* Calculate and set SubPicture scaling (untested, unused yet) */
4300 set_subpict_scale_factor(SISOverlayPtr pOverlay
, ScrnInfoPtr pScrn
,
4301 SISPortPrivPtr pPriv
, int index
, int iscrt2
)
4303 SISPtr pSiS
= SISPTR(pScrn
);
4307 int dstW
= pOverlay
->SubPictdstBox
.x2
- pOverlay
->SubPictdstBox
.x1
;
4308 int dstH
= pOverlay
->SubPictdstBox
.y2
- pOverlay
->SubPictdstBox
.y1
;
4309 int srcW
= pOverlay
->SubPictsrcW
;
4310 int srcH
= pOverlay
->SubPictsrcH
;
4311 CARD16 LCDheight
= pSiS
->LCDheight
;
4312 int srcPitch
= pOverlay
->SubPictOrigPitch
;
4313 int origdstH
= dstH
;
4315 /* Stretch image due to idiotic LCD "auto"-scaling */
4316 /* INCOMPLETE and INCORRECT - See set_scale_factor() */
4317 if( (pPriv
->bridgeIsSlave
) && (pSiS
->VBFlags
& CRT2_LCD
) ) {
4318 dstH
= (dstH
* LCDheight
) / pOverlay
->SCREENheight
;
4319 } else if((index
) && (pSiS
->VBFlags
& CRT2_LCD
)) {
4320 dstH
= (dstH
* LCDheight
) / pOverlay
->SCREENheight
;
4321 if(pPriv
->displayMode
== DISPMODE_MIRROR
) flag
= 1;
4325 pOverlay
->SubPictHUSF
= 0x00;
4326 pOverlay
->SubPictIntBit
= 0x01;
4327 } else if(dstW
> srcW
) {
4328 pOverlay
->SubPictHUSF
= (srcW
<< 16) / dstW
;
4329 pOverlay
->SubPictIntBit
= 0x00;
4334 while (srcW
>= tmpW
) {
4338 pOverlay
->SubPictwHPre
= (CARD8
)(I
- 1);
4341 pOverlay
->SubPictHUSF
= ((srcW
- dstW
) << 16) / dstW
;
4343 pOverlay
->SubPictHUSF
= 0x00;
4345 pOverlay
->SubPictIntBit
= 0x01;
4349 pOverlay
->SubPictVUSF
= 0x00;
4350 pOverlay
->SubPictIntBit
|= 0x02;
4351 } else if(dstH
> srcH
) {
4353 pOverlay
->SubPictVUSF
= (srcH
<< 16) / dstH
;
4354 /* pOverlay->SubPictIntBit |= 0x00; */
4358 pOverlay
->SubPictIntBit
|= 0x02;
4361 pOverlay
->SubPictVUSF
= ((srcH
- dstH
) << 16) / dstH
;
4362 /* TW: Needed for LCD-scaling modes */
4363 if((flag
) && (mult
= (srcH
/ origdstH
)) >= 2)
4364 pOverlay
->SubPictPitch
/= mult
;
4366 if(((srcPitch
* I
)>>2) > 0xFFF) {
4367 I
= (0xFFF*2/srcPitch
);
4368 pOverlay
->SubPictVUSF
= 0xFFFF;
4372 pOverlay
->SubPictVUSF
= ((srcH
- dstH
) << 16) / dstH
;
4374 pOverlay
->SubPictVUSF
= 0x00;
4376 /* set video frame buffer offset */
4377 pOverlay
->SubPictPitch
= (CARD16
)(srcPitch
*I
);
4380 /* set SubPicture scale factor */
4381 setvideoreg (pSiS
, Index_VI_SubPict_Hor_Scale_Low
, (CARD8
)(pOverlay
->SubPictHUSF
));
4382 setvideoreg (pSiS
, Index_VI_SubPict_Hor_Scale_High
, (CARD8
)((pOverlay
->SubPictHUSF
)>>8));
4383 setvideoreg (pSiS
, Index_VI_SubPict_Vert_Scale_Low
, (CARD8
)(pOverlay
->SubPictVUSF
));
4384 setvideoreg (pSiS
, Index_VI_SubPict_Vert_Scale_High
,(CARD8
)((pOverlay
->SubPictVUSF
)>>8));
4386 setvideoregmask (pSiS
, Index_VI_SubPict_Scale_Control
,
4387 (pOverlay
->SubPictIntBit
<< 3) |
4388 (pOverlay
->SubPictwHPre
), 0x7f);
4391 /* Set SubPicture Preset (yet unused) */
4393 set_subpict_preset(SISPtr pSiS
, SISOverlayPtr pOverlay
)
4398 temp
= pOverlay
->SubPictPreset
>> 4; /* TW: 630 <-> 315 ? */
4400 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Preset_Low
, temp
& 0xFF);
4401 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Preset_Middle
, (temp
>>8) & 0xFF);
4402 data
= getvideoreg(pSiS
,Index_VI_SubPict_Buf_Start_High
);
4407 setvideoreg(pSiS
,Index_VI_SubPict_Buf_Start_High
, data
);
4411 enable_subpict_overlay(SISPtr pSiS
, Bool enable
)
4413 setvideoregmask(pSiS
, Index_VI_SubPict_Scale_Control
,
4414 enable
? 0x40 : 0x00,
4418 /* Set overlay for subpicture */
4420 set_subpict_overlay(SISPtr pSiS
, SISOverlayPtr pOverlay
, SISPortPrivPtr pPriv
, int index
)
4422 ScrnInfoPtr pScrn
= pSiS
->pScrn
;
4424 set_subpict_pitch(pSiS
, &overlay
, index
);
4425 set_subpict_start_offset(pSiS
, &overlay
, index
);
4426 set_subpict_scale_factor(&overlay
, pScrn
, pPriv
, index
);
4427 /* set_subpict_preset(pSiS, &overlay); */
4428 /* enable_subpict_overlay(pSiS, 1); */
4432 /* Set MPEG Field Preset (yet unused) */
4434 set_mpegfield_preset(SISPtr pSiS
, SISOverlayPtr pOverlay
)
4436 setvideoreg(pSiS
,Index_MPEG_Y_Buf_Preset_Low
, pOverlay
->MPEG_Y
& 0xFF);
4437 setvideoreg(pSiS
,Index_MPEG_Y_Buf_Preset_Middle
, (pOverlay
->MPEG_Y
>>8) & 0xFF);
4439 setvideoreg(pSiS
,Index_MPEG_UV_Buf_Preset_Low
, pOverlay
->MPEG_UV
& 0xFF);
4440 setvideoreg(pSiS
,Index_MPEG_UV_Buf_Preset_Middle
, (pOverlay
->MPEG_UV
>>8) & 0xFF);
4442 setvideoreg(pSiS
,Index_MPEG_Y_UV_Buf_Preset_High
,
4443 ((pOverlay
->MPEG_Y
>>16) & 0x0F) | ((pOverlay
->MPEG_UV
>>12) & 0xF0));
4447 set_mpegfield_scale(SISPtr pSiS
, SISOverlayPtr pOverlay
)
4452 #endif /* ------------------------------------------------------------------- */