smi_video.c revision e4f6584c
109885543Smrg/*
209885543SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
37104f784SmrgCopyright (C) 2000,2008 Silicon Motion, Inc.  All Rights Reserved.
409885543SmrgCopyright (C) 2001 Corvin Zahn.  All Rights Reserved.
57104f784SmrgCopyright (C) 2008 Mandriva Linux.  All Rights Reserved.
609885543Smrg
709885543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of
809885543Smrgthis software and associated documentation files (the "Software"), to deal in
909885543Smrgthe Software without restriction, including without limitation the rights to
1009885543Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1109885543Smrgof the Software, and to permit persons to whom the Software is furnished to do
1209885543Smrgso, subject to the following conditions:
1309885543Smrg
1409885543SmrgThe above copyright notice and this permission notice shall be included in all
1509885543Smrgcopies or substantial portions of the Software.
1609885543Smrg
1709885543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1809885543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
1909885543SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2009885543SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2109885543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2209885543SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2309885543Smrg
2409885543SmrgExcept as contained in this notice, the names of the XFree86 Project and
2509885543SmrgSilicon Motion shall not be used in advertising or otherwise to promote the
2609885543Smrgsale, use or other dealings in this Software without prior written
2709885543Smrgauthorization from the XFree86 Project and silicon Motion.
2809885543Smrg*/
2909885543Smrg
307104f784Smrg
3109885543Smrg/*
327104f784Smrg  Corvin Zahn <zahn@zac.de>	Date:   2.11.2001
337104f784Smrg    - SAA7111 support
347104f784Smrg    - supports attributes: XV_ENCODING, XV_BRIGHTNESS, XV_CONTRAST,
357104f784Smrg      XV_SATURATION, XV_HUE, XV_COLORKEY, XV_INTERLACED
367104f784Smrg      XV_CAPTURE_BRIGHTNESS can be used to set brightness in the capture device
377104f784Smrg    - bug fixes
387104f784Smrg    - tries not to use acceleration functions
397104f784Smrg    - interlaced video for double vertical resolution
407104f784Smrg	XV_INTERLACED = 0: only one field of an interlaced video signal is
417104f784Smrg			   displayed:
427104f784Smrg			-> half vertical resolution, but no comb like artifacts
437104f784Smrg			   from moving vertical edges
447104f784Smrg	XV_INTERLACED = 1: both fields of an interlaced video signal are
457104f784Smrg			   displayed:
467104f784Smrg			-> full vertical resolution, but comb like artifacts from
477104f784Smrg			   moving vertical edges
487104f784Smrg	The default value can be set with the driver option Interlaced
4909885543Smrg*/
5009885543Smrg
5109885543Smrg
5209885543Smrg#ifdef HAVE_CONFIG_H
5309885543Smrg#include "config.h"
5409885543Smrg#endif
5509885543Smrg
5609885543Smrg#include "smi.h"
5709885543Smrg#include "smi_video.h"
5809885543Smrg
597104f784Smrg#include "xf86Crtc.h"
6009885543Smrg
6109885543Smrg#undef MIN
6209885543Smrg#undef ABS
6309885543Smrg#undef CLAMP
6409885543Smrg#undef ENTRIES
6509885543Smrg
6609885543Smrg#define MIN(a, b) (((a) < (b)) ? (a) : (b))
6709885543Smrg#define ABS(n) (((n) < 0) ? -(n) : (n))
6809885543Smrg#define CLAMP(v, min, max) (((v) < (min)) ? (min) : MIN(v, max))
6909885543Smrg
7009885543Smrg#define ENTRIES(array) (sizeof(array) / sizeof((array)[0]))
7109885543Smrg#define nElems(x)		(sizeof(x) / sizeof(x[0]))
7209885543Smrg
7309885543Smrg#define MAKE_ATOM(a)	MakeAtom(a, sizeof(a) - 1, TRUE)
7409885543Smrg
7509885543Smrg#if SMI_USE_VIDEO
7609885543Smrg#include "dixstruct.h"
7709885543Smrg
7809885543Smrg
7909885543Smrgstatic int SMI_AddEncoding(XF86VideoEncodingPtr enc, int i,
8009885543Smrg			   int norm, int input, int channel);
8109885543Smrgstatic void SMI_BuildEncodings(SMI_PortPtr p);
8209885543Smrg
8309885543Smrgstatic XF86VideoAdaptorPtr SMI_SetupVideo(ScreenPtr pScreen);
8409885543Smrgstatic void SMI_ResetVideo(ScrnInfoPtr pScrn);
8509885543Smrg
8609885543Smrg#if SMI_USE_CAPTURE
8709885543Smrgstatic int SMI_PutVideo(ScrnInfoPtr pScrn,
8809885543Smrg		short vid_x, short vid_y, short drw_x, short drw_y,
8909885543Smrg		short vid_w, short vid_h, short drw_w, short drw_h,
9009885543Smrg		RegionPtr clipBoxes, pointer data, DrawablePtr);
9109885543Smrg#endif
9209885543Smrgstatic void SMI_StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown);
9309885543Smrgstatic int SMI_SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
9409885543Smrg		INT32 value, pointer data);
9509885543Smrgstatic int SMI_GetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
9609885543Smrg		INT32 *value, pointer data);
9709885543Smrgstatic void SMI_QueryBestSize(ScrnInfoPtr pScrn, Bool motion,
9809885543Smrg		short vid_w, short vid_h, short drw_w, short drw_h,
9909885543Smrg		unsigned int *p_w, unsigned int *p_h, pointer data);
10009885543Smrgstatic int SMI_PutImage(ScrnInfoPtr pScrn,
10109885543Smrg		short src_x, short src_y, short drw_x, short drw_y,
10209885543Smrg		short src_w, short src_h, short drw_w, short drw_h,
10309885543Smrg		int id, unsigned char *buf, short width, short height, Bool sync,
10409885543Smrg		RegionPtr clipBoxes, pointer data, DrawablePtr);
10509885543Smrgstatic int SMI_QueryImageAttributes(ScrnInfoPtr pScrn,
10609885543Smrg		int id, unsigned short *width, unsigned short *height,
10709885543Smrg		int *picthes, int *offsets);
10809885543Smrg
10909885543Smrgstatic void SMI_DisplayVideo(ScrnInfoPtr pScrn, int id, int offset,
11009885543Smrg		short width, short height, int pitch, int x1, int y1, int x2, int y2,
11109885543Smrg		BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h);
1127104f784Smrgstatic void SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset,
1137104f784Smrg				     short width, short height, int pitch,
1147104f784Smrg				     int x1, int y1, int x2, int y2,
1157104f784Smrg				     BoxPtr dstBox, short vid_w, short vid_h,
1167104f784Smrg				     short drw_w, short drw_h,
1177104f784Smrg				     RegionPtr clipboxes);
1187104f784Smrgstatic void SMI_DisplayVideo0501(ScrnInfoPtr pScrn, int id, int offset,
1197104f784Smrg				 short width, short height, int pitch,
1207104f784Smrg				 int x1, int y1, int x2, int y2,
1217104f784Smrg				 BoxPtr dstBox, short vid_w, short vid_h,
1227104f784Smrg				 short drw_w, short drw_h);
12309885543Smrgstatic void SMI_DisplayVideo0730(ScrnInfoPtr pScrn, int id, int offset,
12409885543Smrg		short width, short height, int pitch, int x1, int y1, int x2, int y2,
12509885543Smrg		BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h);
12609885543Smrgstatic void SMI_BlockHandler(int i, pointer blockData, pointer pTimeout,
12709885543Smrg		pointer pReadMask);
12809885543Smrg/*static int SMI_SendI2C(ScrnInfoPtr pScrn, CARD8 device, char *devName,
12909885543Smrg        SMI_I2CDataPtr i2cData);*/
13009885543Smrg
13109885543Smrgstatic void SMI_InitOffscreenImages(ScreenPtr pScreen);
13209885543Smrgstatic void SMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area);
13309885543Smrg
1347104f784Smrgstatic void CopyYV12ToVideoMem(unsigned char *src1, unsigned char *src2,
1357104f784Smrg			       unsigned char *src3, unsigned char *dst,
1367104f784Smrg			       int src1Pitch, int src23Pitch, int dstPitch,
1377104f784Smrg			       int height, int width);
13809885543Smrgstatic int SMI_AllocSurface(ScrnInfoPtr pScrn,
13909885543Smrg		int id, unsigned short width, unsigned short height,
14009885543Smrg		XF86SurfacePtr surface);
14109885543Smrgstatic int SMI_FreeSurface(XF86SurfacePtr surface);
14209885543Smrgstatic int SMI_DisplaySurface(XF86SurfacePtr surface,
14309885543Smrg		short vid_x, short vid_y, short drw_x, short drw_y,
14409885543Smrg		short vid_w, short vid_h, short drw_w, short drw_h,
14509885543Smrg		RegionPtr clipBoxes);
14609885543Smrgstatic int SMI_StopSurface(XF86SurfacePtr surface);
14709885543Smrgstatic int SMI_GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 *value);
14809885543Smrgstatic int SMI_SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 value);
14909885543Smrg
15009885543Smrgstatic int SetAttr(ScrnInfoPtr pScrn, int i, int value);
15109885543Smrgstatic int SetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value);
15209885543Smrgstatic int SetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value);
15309885543Smrgstatic void SetKeyReg(SMIPtr pSmi, int reg, int value);
15409885543Smrg
15509885543Smrg/**
15609885543Smrg * Atoms
15709885543Smrg */
15809885543Smrg
15909885543Smrgstatic Atom xvColorKey;
16009885543Smrgstatic Atom xvEncoding;
16109885543Smrgstatic Atom xvBrightness,xvCapBrightness, xvContrast, xvSaturation, xvHue;
16209885543Smrgstatic Atom xvInterlaced;
16309885543Smrg
16409885543Smrg
16509885543Smrg/******************************************************************************\
16609885543Smrg**																			  **
16709885543Smrg**                           C A P A B I L I T I E S                          **
16809885543Smrg**																			  **
16909885543Smrg\******************************************************************************/
17009885543Smrg
17109885543Smrg
17209885543Smrg/**************************************************************************/
17309885543Smrg/* input channels */
17409885543Smrg
17509885543Smrg#define N_COMPOSITE_CHANNELS 4
17609885543Smrg#define N_SVIDEO_CHANNELS 2
17709885543Smrg
17809885543Smrg#define N_VIDEO_INPUTS 2
17909885543Smrgtypedef enum _VideoInput { VID_COMPOSITE, VID_SVIDEO } VideoInput;
18009885543Smrg
18109885543Smrg
18209885543Smrg/**************************************************************************/
18309885543Smrg/* video input formats */
18409885543Smrg
18509885543Smrgtypedef struct _VideoInputDataRec {
18609885543Smrg    char* name;
18709885543Smrg} VideoInputDataRec;
18809885543Smrg
18909885543Smrgstatic VideoInputDataRec VideoInputs[] = {
19009885543Smrg    { "composite" },
19109885543Smrg    { "svideo" }
19209885543Smrg};
19309885543Smrg
19409885543Smrg
19509885543Smrg/**************************************************************************/
19609885543Smrg/* video norms */
19709885543Smrg
19809885543Smrg#define N_VIDEO_NORMS 3
19909885543Smrgtypedef enum _VideoNorm { PAL, NTSC, SECAM } VideoNorm;
20009885543Smrg
20109885543Smrgtypedef struct _VideoNormDataRec {
20209885543Smrg    char* name;
20309885543Smrg    unsigned long Wt;
20409885543Smrg    unsigned long Wa;
20509885543Smrg    unsigned long Ht;
20609885543Smrg    unsigned long Ha;
20709885543Smrg    unsigned long HStart;
20809885543Smrg    unsigned long VStart;
20909885543Smrg    XvRationalRec rate;
21009885543Smrg} VideoNormDataRec;
21109885543Smrg
21209885543Smrg
21309885543Smrgstatic VideoNormDataRec VideoNorms[] =
21409885543Smrg{
21509885543Smrg    /* PAL-BDGHI */
21609885543Smrg    {"pal", 864, 704, 625, 576, 16, 16, { 1, 50 }},
21709885543Smrg    /* NTSC */
21809885543Smrg    {"ntsc", 858, 704, 525, 480, 21, 8, { 1001, 60000 }},
21909885543Smrg    /* SECAM (not tested) */
22009885543Smrg    {"secam", 864, 7040, 625, 576, 31, 16, { 1, 50 }},
22109885543Smrg};
22209885543Smrg
22309885543Smrg
22409885543Smrg/**************************************************************************/
22509885543Smrg/* number of (generated) XV_ENCODING vaulues */
22609885543Smrg#define N_ENCODINGS ((N_VIDEO_NORMS) * (N_COMPOSITE_CHANNELS + N_SVIDEO_CHANNELS))
22709885543Smrg
22809885543Smrg
22909885543Smrg/**************************************************************************/
23009885543Smrg
23109885543Smrgstatic XF86VideoFormatRec SMI_VideoFormats[] =
23209885543Smrg{
23309885543Smrg    { 15, TrueColor },	/* depth, class				*/
23409885543Smrg    { 16, TrueColor },	/* depth, class				*/
23509885543Smrg    { 24, TrueColor },	/* depth, class				*/
23609885543Smrg};
23709885543Smrg
23809885543Smrg
23909885543Smrg/**************************************************************************/
24009885543Smrg
24109885543Smrg/**
24209885543Smrg * Attributes
24309885543Smrg */
24409885543Smrg
24509885543Smrg#define XV_ENCODING_NAME        "XV_ENCODING"
24609885543Smrg#define XV_BRIGHTNESS_NAME      "XV_BRIGHTNESS"
24709885543Smrg#define XV_CAPTURE_BRIGHTNESS_NAME      "XV_CAPTURE_BRIGHTNESS"
24809885543Smrg#define XV_CONTRAST_NAME        "XV_CONTRAST"
24909885543Smrg#define XV_SATURATION_NAME      "XV_SATURATION"
25009885543Smrg#define XV_HUE_NAME             "XV_HUE"
25109885543Smrg#define XV_COLORKEY_NAME        "XV_COLORKEY"
25209885543Smrg#define XV_INTERLACED_NAME      "XV_INTERLACED"
25309885543Smrg
25409885543Smrg
25509885543Smrg/* fixed order! */
25609885543Smrgstatic XF86AttributeRec SMI_VideoAttributesSAA711x[N_ATTRS] = {
25709885543Smrg    {XvSettable | XvGettable,        0, N_ENCODINGS-1, XV_ENCODING_NAME},
25809885543Smrg    {XvSettable | XvGettable,        0,           255, XV_BRIGHTNESS_NAME},
25909885543Smrg    {XvSettable | XvGettable,        0,           255, XV_CAPTURE_BRIGHTNESS_NAME},
26009885543Smrg    {XvSettable | XvGettable,        0,           127, XV_CONTRAST_NAME},
26109885543Smrg    {XvSettable | XvGettable,        0,           127, XV_SATURATION_NAME},
26209885543Smrg    {XvSettable | XvGettable,     -128,           127, XV_HUE_NAME},
26309885543Smrg    {XvSettable | XvGettable, 0x000000,      0xFFFFFF, XV_COLORKEY_NAME},
26409885543Smrg    {XvSettable | XvGettable,        0,             1, XV_INTERLACED_NAME},
26509885543Smrg};
26609885543Smrg
26709885543Smrgstatic XF86AttributeRec SMI_VideoAttributes[2] = {
26809885543Smrg    {XvSettable | XvGettable,        0,           255, XV_BRIGHTNESS_NAME},
26909885543Smrg    {XvSettable | XvGettable, 0x000000,      0xFFFFFF, XV_COLORKEY_NAME},
27009885543Smrg};
27109885543Smrg
27209885543Smrg
27309885543Smrg/**************************************************************************/
27409885543Smrgstatic XF86ImageRec SMI_VideoImages[] =
27509885543Smrg{
27609885543Smrg    XVIMAGE_YUY2,
27709885543Smrg    XVIMAGE_YV12,
27809885543Smrg    XVIMAGE_I420,
27909885543Smrg    {
28009885543Smrg	FOURCC_RV15,			/* id				*/
28109885543Smrg	XvRGB,				/* type				*/
28209885543Smrg	LSBFirst,			/* byte_order			*/
28309885543Smrg	{ 'R', 'V' ,'1', '5',
28409885543Smrg	  0x00, '5',  0x00, 0x00,
28509885543Smrg	  0x00, 0x00, 0x00, 0x00,
28609885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
28709885543Smrg	16,				/* bits_per_pixel		*/
28809885543Smrg	XvPacked,			/* format			*/
28909885543Smrg	1,				/* num_planes			*/
29009885543Smrg	15,				/* depth			*/
29109885543Smrg	0x001F, 0x03E0, 0x7C00,		/* red_mask, green, blue	*/
29209885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
29309885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
29409885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
29509885543Smrg	{ 'R', 'V', 'B' },		/* component_order		*/
29609885543Smrg	XvTopToBottom			/* scaline_order		*/
29709885543Smrg    },
29809885543Smrg    {
29909885543Smrg	FOURCC_RV16,			/* id				*/
30009885543Smrg	XvRGB,				/* type				*/
30109885543Smrg	LSBFirst,			/* byte_order			*/
30209885543Smrg	{ 'R', 'V' ,'1', '6',
30309885543Smrg	  0x00, 0x00, 0x00, 0x00,
30409885543Smrg	  0x00, 0x00, 0x00, 0x00,
30509885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
30609885543Smrg	16,				/* bits_per_pixel		*/
30709885543Smrg	XvPacked,			/* format			*/
30809885543Smrg	1,				/* num_planes			*/
30909885543Smrg	16,				/* depth			*/
31009885543Smrg	0x001F, 0x07E0, 0xF800,		/* red_mask, green, blue	*/
31109885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
31209885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
31309885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
31409885543Smrg	{ 'R', 'V', 'B' },		/* component_order		*/
31509885543Smrg	XvTopToBottom			/* scaline_order		*/
31609885543Smrg    },
31709885543Smrg    {
31809885543Smrg	FOURCC_RV24,			/* id				*/
31909885543Smrg	XvRGB,				/* type				*/
32009885543Smrg	LSBFirst,			/* byte_order			*/
32109885543Smrg	{ 'R', 'V' ,'2', '4',
32209885543Smrg	  0x00, 0x00, 0x00, 0x00,
32309885543Smrg	  0x00, 0x00, 0x00, 0x00,
32409885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
32509885543Smrg	24,				/* bits_per_pixel		*/
32609885543Smrg	XvPacked,			/* format			*/
32709885543Smrg	1,				/* num_planes			*/
32809885543Smrg	24,				/* depth			*/
32909885543Smrg	0x0000FF, 0x00FF00, 0xFF0000,	/* red_mask, green, blue	*/
33009885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
33109885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
33209885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
33309885543Smrg	{ 'R', 'V', 'B' },		/* component_order			*/
33409885543Smrg	XvTopToBottom			/* scaline_order			*/
33509885543Smrg    },
33609885543Smrg    {
33709885543Smrg	FOURCC_RV32,			/* id				*/
33809885543Smrg	XvRGB,				/* type				*/
33909885543Smrg	LSBFirst,			/* byte_order			*/
34009885543Smrg	{ 'R', 'V' ,'3', '2',
34109885543Smrg	  0x00, 0x00, 0x00, 0x00,
34209885543Smrg	  0x00, 0x00, 0x00, 0x00,
34309885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
34409885543Smrg	32,				/* bits_per_pixel		*/
34509885543Smrg	XvPacked,			/* format			*/
34609885543Smrg	1,				/* num_planes			*/
34709885543Smrg	24,				/* depth			*/
34809885543Smrg	0x0000FF, 0x00FF00, 0xFF0000,	/* red_mask, green, blue	*/
34909885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
35009885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
35109885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
35209885543Smrg	{ 'R', 'V', 'B' },		/* component_order			*/
35309885543Smrg	XvTopToBottom			/* scaline_order			*/
35409885543Smrg    },
35509885543Smrg};
35609885543Smrg
35709885543Smrg
3587104f784Smrg/**************************************************************************/
3597104f784Smrgstatic XF86ImageRec SMI501_VideoImages[] = {
3607104f784Smrg    XVIMAGE_YUY2,
3617104f784Smrg    XVIMAGE_YV12,
3627104f784Smrg    XVIMAGE_I420,
3637104f784Smrg    {
3647104f784Smrg     FOURCC_RV16,		/* id                                           */
3657104f784Smrg     XvRGB,			/* type                                         */
3667104f784Smrg     LSBFirst,			/* byte_order                           */
3677104f784Smrg     {'R', 'V', '1', '6',
3687104f784Smrg      0x00, 0x00, 0x00, 0x00,
3697104f784Smrg      0x00, 0x00, 0x00, 0x00,
3707104f784Smrg      0x00, 0x00, 0x00, 0x00},	/* guid                                         */
3717104f784Smrg     16,			/* bits_per_pixel                       */
3727104f784Smrg     XvPacked,			/* format                                       */
3737104f784Smrg     1,				/* num_planes                           */
3747104f784Smrg     16,			/* depth                                        */
3757104f784Smrg     0x001F, 0x07E0, 0xF800,	/* red_mask, green, blue        */
3767104f784Smrg     0, 0, 0,			/* y_sample_bits, u, v          */
3777104f784Smrg     0, 0, 0,			/* horz_y_period, u, v          */
3787104f784Smrg     0, 0, 0,			/* vert_y_period, u, v          */
3797104f784Smrg     {'R', 'V', 'B'},		/* component_order                      */
3807104f784Smrg     XvTopToBottom		/* scaline_order                        */
3817104f784Smrg     },
3827104f784Smrg    {
3837104f784Smrg     FOURCC_RV32,		/* id                                           */
3847104f784Smrg     XvRGB,			/* type                                         */
3857104f784Smrg     LSBFirst,			/* byte_order                           */
3867104f784Smrg     {'R', 'V', '3', '2',
3877104f784Smrg      0x00, 0x00, 0x00, 0x00,
3887104f784Smrg      0x00, 0x00, 0x00, 0x00,
3897104f784Smrg      0x00, 0x00, 0x00, 0x00},	/* guid                                         */
3907104f784Smrg     32,			/* bits_per_pixel                       */
3917104f784Smrg     XvPacked,			/* format                                       */
3927104f784Smrg     1,				/* num_planes                           */
3937104f784Smrg     24,			/* depth                                        */
3947104f784Smrg     0x0000FF, 0x00FF00, 0xFF0000,	/* red_mask, green, blue        */
3957104f784Smrg     0, 0, 0,			/* y_sample_bits, u, v          */
3967104f784Smrg     0, 0, 0,			/* horz_y_period, u, v          */
3977104f784Smrg     0, 0, 0,			/* vert_y_period, u, v          */
3987104f784Smrg     {'R', 'V', 'B'},		/* component_order                      */
3997104f784Smrg     XvTopToBottom		/* scaline_order                        */
4007104f784Smrg     },
4017104f784Smrg};
4027104f784Smrg
40309885543Smrg/**************************************************************************/
40409885543Smrg
40509885543Smrg/**
40609885543Smrg * SAA7111 video decoder register values
40709885543Smrg */
40809885543Smrg
40909885543Smrg
41009885543Smrg/** SAA7111 control sequences for selecting one out of four
41109885543Smrg    composite input channels */
41209885543Smrgstatic I2CByte SAA7111CompositeChannelSelect[N_COMPOSITE_CHANNELS][4] = {
41309885543Smrg    { 0x02, 0xC0, 0x09, 0x4A}, /* CVBS AI11 */
41409885543Smrg    { 0x02, 0xC1, 0x09, 0x4A}, /* CVBS AI12 */
41509885543Smrg    { 0x02, 0xC2, 0x09, 0x4A}, /* CVBS AI21 */
41609885543Smrg    { 0x02, 0xC3, 0x09, 0x4A}, /* CVBS AI22 */
41709885543Smrg};
41809885543Smrg
41909885543Smrg
42009885543Smrg/** SAA7111 control sequences for selecting one out of two
42109885543Smrg    s-video input channels */
42209885543Smrgstatic I2CByte SAA7111SVideoChannelSelect[N_SVIDEO_CHANNELS][4] = {
42309885543Smrg    { 0x02, 0xC6, 0x09, 0xCA}, /* Y/C AI11/AI21 */
42409885543Smrg    { 0x02, 0xC7, 0x09, 0xCA}, /* Y/C AI12/AI22 */
42509885543Smrg};
42609885543Smrg
42709885543Smrg
42809885543Smrg/** SAA7111 control sequences for selecting one out of three
42909885543Smrg    video norms */
43009885543Smrgstatic I2CByte SAA7111VideoStd[3][8] = {
43109885543Smrg    {0x06, 108, 0x07, 108, 0x08, 0x09, 0x0E, 0x01}, /* PAL */
43209885543Smrg    {0x06, 107, 0x07, 107, 0x08, 0x49, 0x0E, 0x01}, /* NTSC */
43309885543Smrg    {0x06, 108, 0x07, 108, 0x08, 0x01, 0x0E, 0x51}  /* SECAM */
43409885543Smrg};
43509885543Smrg
43609885543Smrg
43709885543Smrg#if 0
43809885543Smrgstatic I2CByte SAA7110InitData[] =
43909885543Smrg{
44009885543Smrg	/* Configuration */
44109885543Smrg    0x00, 0x4C, 0x01, 0x3C, 0x02, 0x00, 0x03, 0xEF,
44209885543Smrg    0x04, 0xBD, 0x05, 0xE2, 0x06, 0x00, 0x07, 0x00,
44309885543Smrg    0x08, 0xF8, 0x09, 0xF8, 0x0A, 0x60, 0x0B, 0x60,
44409885543Smrg    0x0C, 0x00, 0x0D, 0x80, 0x0E, 0x18, 0x0F, 0xD9,
44509885543Smrg    0x10, 0x00, 0x11, 0x2B, 0x12, 0x40, 0x13, 0x40,
44609885543Smrg    0x14, 0x42, 0x15, 0x1A, 0x16, 0xFF, 0x17, 0xDA,
44709885543Smrg    0x18, 0xE6, 0x19, 0x90, 0x20, 0xD9, 0x21, 0x16,
44809885543Smrg    0x22, 0x40, 0x23, 0x40, 0x24, 0x80, 0x25, 0x40,
44909885543Smrg    0x26, 0x80, 0x27, 0x4F, 0x28, 0xFE, 0x29, 0x01,
45009885543Smrg    0x2A, 0xCF, 0x2B, 0x0F, 0x2C, 0x03, 0x2D, 0x01,
45109885543Smrg    0x2E, 0x83, 0x2F, 0x03, 0x30, 0x40, 0x31, 0x35,
45209885543Smrg    0x32, 0x02, 0x33, 0x8C, 0x34, 0x03,
45309885543Smrg
45409885543Smrg	/* NTSC */
45509885543Smrg    0x11, 0x2B, 0x0F, 0xD9,
45609885543Smrg
45709885543Smrg	/* RCA input connector */
45809885543Smrg    0x06, 0x00, 0x0E, 0x18, 0x20, 0xD9, 0x21, 0x16,
45909885543Smrg    0x22, 0x40, 0x2C, 0x03,
46009885543Smrg
46109885543Smrg};
46209885543Smrg#endif
46309885543Smrg
46409885543Smrgstatic I2CByte SAA7111InitData[] =
46509885543Smrg{
46609885543Smrg    0x11, 0x1D, /* 0D D0=1: automatic colour killer off
46709885543Smrg		   D1=0: DMSD data to YUV output
46809885543Smrg		   D2=1: output enable H/V sync on
46909885543Smrg		   D3=1: output enable YUV data on */
47009885543Smrg    0x02, 0xC0, /* Mode 0 */
47109885543Smrg    0x03, 0x23, /* automatic gain */
47209885543Smrg    0x04, 0x00, /*  */
47309885543Smrg    0x05, 0x00, /*  */
47409885543Smrg    0x06, 108,  /* hor sync begin */
47509885543Smrg    0x07, 108,  /* hor sync stop */
47609885543Smrg    0x08, 0x88, /* sync control:
47709885543Smrg		   D1-0=00: VNOI = normal mode
47809885543Smrg		   D2=0: PLL closed
47909885543Smrg		   D3=1: VTR mode
48009885543Smrg		   D7=1: automatic field detection */
48109885543Smrg    0x09, 0x41, /* 4A luminance control */
48209885543Smrg    0x0A, 0x80, /* brightness = 128 (CCIR level) */
48309885543Smrg    0x0B, 0x40, /* contrast = 1.0 */
48409885543Smrg    0x0C, 0x40, /* crominance = 1.0 (CCIR level) */
48509885543Smrg    0x0D, 0x00, /* hue = 0 */
48609885543Smrg    0x0E, 0x01, /* chroma bandwidth = nominal
48709885543Smrg		   fast colour time constant = nominal
48809885543Smrg		   chrom comp filter on
48909885543Smrg		   colour standard PAL BGHI, NTSC M */
49009885543Smrg    0x10, 0x48, /* luminance delay compensation = 0
49109885543Smrg		   VRLN = 1
49209885543Smrg		   fine pos of hs = 0
49309885543Smrg		   output format = YUV 422 */
49409885543Smrg    0x12, 0x00, /* 20 D5=1: VPO in tristate */
49509885543Smrg    0x13, 0x00,
49609885543Smrg    0x15, 0x00,
49709885543Smrg    0x16, 0x00,
49809885543Smrg    0x17, 0x00,
49909885543Smrg
50009885543Smrg};
50109885543Smrg
50209885543Smrg
50309885543Smrg/**************************************************************************/
50409885543Smrg
50509885543Smrg/**
50609885543Smrg * generates XF86VideoEncoding[i] with video norm norm, video input format
50709885543Smrg * input and video input channel channel
50809885543Smrg */
50909885543Smrgstatic int
51009885543SmrgSMI_AddEncoding(XF86VideoEncodingPtr enc, int i,
51109885543Smrg		int norm, int input, int channel)
51209885543Smrg{
51309885543Smrg    char* norm_string;
51409885543Smrg    char* input_string;
51509885543Smrg    char channel_string[20];
51609885543Smrg
5177104f784Smrg    ENTER();
51809885543Smrg
51909885543Smrg    norm_string = VideoNorms[norm].name;
52009885543Smrg    input_string = VideoInputs[input].name;
52109885543Smrg    sprintf(channel_string, "%d", channel);
52209885543Smrg    enc[i].id     = i;
52309885543Smrg    enc[i].name   = xalloc(strlen(norm_string) +
52409885543Smrg			   strlen(input_string) +
52509885543Smrg			   strlen(channel_string)+3);
5267104f784Smrg    if (NULL == enc[i].name)
5277104f784Smrg	LEAVE(-1);
5287104f784Smrg
52909885543Smrg    enc[i].width  = VideoNorms[norm].Wa;
53009885543Smrg    enc[i].height = VideoNorms[norm].Ha;
53109885543Smrg    enc[i].rate   = VideoNorms[norm].rate;
53209885543Smrg    sprintf(enc[i].name,"%s-%s-%s", norm_string, input_string, channel_string);
53309885543Smrg
5347104f784Smrg    LEAVE(0);
53509885543Smrg}
53609885543Smrg
53709885543Smrg
53809885543Smrg/**
53909885543Smrg * builds XF86VideoEncodings with all legal combinations of video norm,
54009885543Smrg * video input format and video input channel
54109885543Smrg */
54209885543Smrgstatic void
54309885543SmrgSMI_BuildEncodings(SMI_PortPtr p)
54409885543Smrg{
54509885543Smrg    int ch, n;
54609885543Smrg
5477104f784Smrg    ENTER();
54809885543Smrg
54909885543Smrg    /* allocate memory for encoding array */
55009885543Smrg    p->enc = xalloc(sizeof(XF86VideoEncodingRec) * N_ENCODINGS);
55109885543Smrg    if (NULL == p->enc)
55209885543Smrg	goto fail;
55309885543Smrg    memset(p->enc,0,sizeof(XF86VideoEncodingRec) * N_ENCODINGS);
55409885543Smrg    /* allocate memory for video norm array */
55509885543Smrg    p->norm = xalloc(sizeof(int) * N_ENCODINGS);
55609885543Smrg    if (NULL == p->norm)
55709885543Smrg	goto fail;
55809885543Smrg    memset(p->norm,0,sizeof(int) * N_ENCODINGS);
55909885543Smrg    /* allocate memory for video input format array */
56009885543Smrg    p->input = xalloc(sizeof(int) * N_ENCODINGS);
56109885543Smrg    if (NULL == p->input)
56209885543Smrg	goto fail;
56309885543Smrg    memset(p->input,0,sizeof(int) * N_ENCODINGS);
56409885543Smrg    /* allocate memory for video channel number array */
56509885543Smrg    p->channel = xalloc(sizeof(int) * N_ENCODINGS);
56609885543Smrg    if (NULL == p->channel)
56709885543Smrg	goto fail;
56809885543Smrg    memset(p->channel,0,sizeof(int) * N_ENCODINGS);
56909885543Smrg
57009885543Smrg    /* fill arrays */
57109885543Smrg    p->nenc = 0;
57209885543Smrg    for (ch = 0; ch < N_COMPOSITE_CHANNELS; ch++) {
57309885543Smrg	for (n = 0; n < N_VIDEO_NORMS; n++) {
57409885543Smrg	    SMI_AddEncoding(p->enc, p->nenc, n, VID_COMPOSITE, ch);
57509885543Smrg	    p->norm[p->nenc]  = n;
57609885543Smrg	    p->input[p->nenc] = VID_COMPOSITE;
57709885543Smrg	    p->channel[p->nenc] = ch;
57809885543Smrg	    p->nenc++;
57909885543Smrg	}
58009885543Smrg    }
58109885543Smrg    for (ch = 0; ch < N_SVIDEO_CHANNELS; ch++) {
58209885543Smrg	for (n = 0; n < N_VIDEO_NORMS; n++) {
58309885543Smrg	    SMI_AddEncoding(p->enc, p->nenc, n, VID_SVIDEO, ch);
58409885543Smrg	    p->norm[p->nenc]  = n;
58509885543Smrg	    p->input[p->nenc] = VID_SVIDEO;
58609885543Smrg	    p->channel[p->nenc] = ch;
58709885543Smrg	    p->nenc++;
58809885543Smrg	}
58909885543Smrg    }
5907104f784Smrg    LEAVE();
59109885543Smrg
59209885543Smrg fail:
59309885543Smrg    if (p->input) xfree(p->input);
59409885543Smrg    p->input = NULL;
59509885543Smrg    if (p->norm) xfree(p->norm);
59609885543Smrg    p->norm = NULL;
59709885543Smrg    if (p->channel) xfree(p->channel);
59809885543Smrg    p->channel = NULL;
59909885543Smrg    if (p->enc) xfree(p->enc);
60009885543Smrg    p->enc = NULL;
60109885543Smrg    p->nenc = 0;
6027104f784Smrg    LEAVE();
60309885543Smrg}
60409885543Smrg
60509885543Smrg
60609885543Smrg/******************************************************************************\
60709885543Smrg**                                                                            **
60809885543Smrg**                  X V E X T E N S I O N   I N T E R F A C E                 **
60909885543Smrg**                                                                            **
61009885543Smrg\******************************************************************************/
61109885543Smrg
61209885543Smrgvoid
61309885543SmrgSMI_InitVideo(ScreenPtr pScreen)
61409885543Smrg{
61509885543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
61609885543Smrg    XF86VideoAdaptorPtr *ptrAdaptors, *newAdaptors = NULL;
61709885543Smrg    XF86VideoAdaptorPtr newAdaptor = NULL;
61809885543Smrg    int numAdaptors;
61909885543Smrg
6207104f784Smrg    ENTER();
62109885543Smrg
62209885543Smrg    numAdaptors = xf86XVListGenericAdaptors(pScrn, &ptrAdaptors);
62309885543Smrg
6247104f784Smrg    DEBUG("numAdaptors=%d\n", numAdaptors);
62509885543Smrg
6267104f784Smrg    newAdaptor = SMI_SetupVideo(pScreen);
6277104f784Smrg    DEBUG("newAdaptor=%p\n", newAdaptor);
6287104f784Smrg    SMI_InitOffscreenImages(pScreen);
62909885543Smrg
63009885543Smrg    if (newAdaptor != NULL) {
63109885543Smrg        if (numAdaptors == 0) {
63209885543Smrg            numAdaptors = 1;
63309885543Smrg            ptrAdaptors = &newAdaptor;
63409885543Smrg        } else {
63509885543Smrg            newAdaptors = xalloc((numAdaptors + 1) *
63609885543Smrg                    sizeof(XF86VideoAdaptorPtr*));
63709885543Smrg            if (newAdaptors != NULL) {
63809885543Smrg                memcpy(newAdaptors, ptrAdaptors,
63909885543Smrg                        numAdaptors * sizeof(XF86VideoAdaptorPtr));
64009885543Smrg                newAdaptors[numAdaptors++] = newAdaptor;
64109885543Smrg                ptrAdaptors = newAdaptors;
64209885543Smrg            }
64309885543Smrg        }
64409885543Smrg    }
64509885543Smrg
64609885543Smrg    if (numAdaptors != 0) {
6477104f784Smrg        DEBUG("ScreenInit %i\n",numAdaptors);
64809885543Smrg        xf86XVScreenInit(pScreen, ptrAdaptors, numAdaptors);
64909885543Smrg    }
65009885543Smrg
65109885543Smrg    if (newAdaptors != NULL) {
65209885543Smrg        xfree(newAdaptors);
65309885543Smrg    }
65409885543Smrg
6557104f784Smrg    LEAVE();
65609885543Smrg}
65709885543Smrg
65809885543Smrg
65909885543Smrg/*************************************************************************/
66009885543Smrg
66109885543Smrg/*
66209885543Smrg *  Video codec controls
66309885543Smrg */
66409885543Smrg
66509885543Smrg#if 0
66609885543Smrg/**
66709885543Smrg * scales value value of attribute i to range min, max
66809885543Smrg */
66909885543Smrgstatic int
67009885543SmrgScale(int i, int value, int min, int max)
67109885543Smrg{
67209885543Smrg    return min + (value - SMI_VideoAttributes[i].min_value) * (max - min) /
67309885543Smrg	(SMI_VideoAttributes[i].max_value - SMI_VideoAttributes[i].min_value);
67409885543Smrg}
67509885543Smrg#endif
67609885543Smrg/**
67709885543Smrg * sets video decoder attributes channel, encoding, brightness, contrast, saturation, hue
67809885543Smrg */
67909885543Smrgstatic int
68009885543SmrgSetAttr(ScrnInfoPtr pScrn, int i, int value)
68109885543Smrg{
68209885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
68309885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
68409885543Smrg
68509885543Smrg    if (i < XV_ENCODING || i > XV_HUE)
68609885543Smrg	return BadMatch;
68709885543Smrg
68809885543Smrg    /* clamps value to attribute range */
68909885543Smrg    value = CLAMP(value, SMI_VideoAttributes[i].min_value,
69009885543Smrg		  SMI_VideoAttributes[i].max_value);
69109885543Smrg
69209885543Smrg    if (i == XV_BRIGHTNESS) {
69309885543Smrg	int my_value = (value <= 128? value + 128 : value - 128);
69409885543Smrg	SetKeyReg(pSmi, 0x5C, 0xEDEDED | (my_value << 24));
69509885543Smrg    } else if (pPort->I2CDev.SlaveAddr == SAA7110) {
69609885543Smrg	return SetAttrSAA7110(pScrn, i, value);
69709885543Smrg    } else if (pPort->I2CDev.SlaveAddr == SAA7111) {
69809885543Smrg	return SetAttrSAA7111(pScrn, i, value);
69909885543Smrg    }
70009885543Smrg#if 0
70109885543Smrg    else {
70209885543Smrg	return XvBadAlloc;
70309885543Smrg    }
70409885543Smrg#endif
70509885543Smrg
70609885543Smrg    return Success;
70709885543Smrg}
70809885543Smrg
70909885543Smrg
71009885543Smrg/**
71109885543Smrg * sets SAA7110 video decoder attributes channel, encoding, brightness, contrast, saturation, hue
71209885543Smrg */
71309885543Smrgstatic int
71409885543SmrgSetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value)
71509885543Smrg{
71609885543Smrg    /* not supported */
71709885543Smrg    return XvBadAlloc;
71809885543Smrg}
71909885543Smrg
72009885543Smrg
72109885543Smrg/**
72209885543Smrg * sets SAA7111 video decoder attributes channel, encoding,
72309885543Smrg * brightness, contrast, saturation, hue
72409885543Smrg */
72509885543Smrgstatic int
72609885543SmrgSetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value)
72709885543Smrg{
72809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
72909885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
73009885543Smrg
73109885543Smrg    if (i == XV_ENCODING) {
73209885543Smrg	int norm;
73309885543Smrg	int input;
73409885543Smrg	int channel;
73509885543Smrg	norm = pPort->norm[value];
73609885543Smrg	input = pPort->input[value];
73709885543Smrg	channel = pPort->channel[value];
73809885543Smrg
7397104f784Smrg	DEBUG("SetAttribute XV_ENCODING: %d. norm=%d input=%d channel=%d\n",
7407104f784Smrg	      value, norm, input, channel);
74109885543Smrg
74209885543Smrg	/* set video norm */
74309885543Smrg	if (!xf86I2CWriteVec(&(pPort->I2CDev), SAA7111VideoStd[norm],
74409885543Smrg			     ENTRIES(SAA7111VideoStd[norm]) / 2)) {
74509885543Smrg	    return XvBadAlloc;
74609885543Smrg	}
74709885543Smrg	/* set video input format and channel */
74809885543Smrg	if (input == VID_COMPOSITE) {
74909885543Smrg	    if (!xf86I2CWriteVec(&(pPort->I2CDev),
75009885543Smrg				 SAA7111CompositeChannelSelect[channel],
75109885543Smrg				 ENTRIES(SAA7111CompositeChannelSelect[channel]) / 2)) {
75209885543Smrg		return XvBadAlloc;
75309885543Smrg	    }
75409885543Smrg	} else {
75509885543Smrg	    if (!xf86I2CWriteVec(&(pPort->I2CDev),
75609885543Smrg				 SAA7111SVideoChannelSelect[channel],
75709885543Smrg				 ENTRIES(SAA7111SVideoChannelSelect[channel]) / 2)) {
75809885543Smrg		return XvBadAlloc;
75909885543Smrg	    }
76009885543Smrg	}
76109885543Smrg    } else if (i >= XV_CAPTURE_BRIGHTNESS && i <= XV_HUE) {
76209885543Smrg	int slave_adr = 0;
76309885543Smrg
76409885543Smrg	switch (i) {
76509885543Smrg
76609885543Smrg	case XV_CAPTURE_BRIGHTNESS:
7677104f784Smrg	    DEBUG("SetAttribute XV_BRIGHTNESS: %d\n", value);
76809885543Smrg	    slave_adr = 0x0a;
76909885543Smrg	    break;
77009885543Smrg
77109885543Smrg	case XV_CONTRAST:
7727104f784Smrg	    DEBUG("SetAttribute XV_CONTRAST: %d\n", value);
77309885543Smrg	    slave_adr = 0x0b;
77409885543Smrg	    break;
77509885543Smrg
77609885543Smrg	case XV_SATURATION:
7777104f784Smrg	    DEBUG("SetAttribute XV_SATURATION: %d\n", value);
77809885543Smrg	    slave_adr = 0x0c;
77909885543Smrg	    break;
78009885543Smrg
78109885543Smrg	case XV_HUE:
7827104f784Smrg	    DEBUG("SetAttribute XV_HUE: %d\n", value);
78309885543Smrg	    slave_adr = 0x0d;
78409885543Smrg	    break;
78509885543Smrg
78609885543Smrg	default:
78709885543Smrg	    return XvBadAlloc;
78809885543Smrg	}
78909885543Smrg	if (!xf86I2CWriteByte(&(pPort->I2CDev), slave_adr, (value & 0xff)))
79009885543Smrg	    return XvBadAlloc;
79109885543Smrg    } else {
79209885543Smrg	return BadMatch;
79309885543Smrg    }
79409885543Smrg
79509885543Smrg    /* debug: show registers */
79609885543Smrg    {
79709885543Smrg	I2CByte i2c_bytes[32];
79809885543Smrg	int i;
79909885543Smrg	xf86I2CReadBytes(&(pPort->I2CDev), 0, i2c_bytes, 32);
8007104f784Smrg	DEBUG("SAA7111 Registers\n");
80109885543Smrg	for (i=0; i<32; i++) {
8027104f784Smrg	    DEBUG("%02X=%02X ", i, i2c_bytes[i]);
8037104f784Smrg	    if ((i&7) == 7) DEBUG("\n");
80409885543Smrg	}
80509885543Smrg    }
80609885543Smrg
80709885543Smrg    return Success;
80809885543Smrg}
80909885543Smrg
81009885543Smrg
81109885543Smrg/******************************************************************************\
81209885543Smrg**									      **
81309885543Smrg**	V I D E O   M A N A G E M E N T					      **
81409885543Smrg**									      **
81509885543Smrg\******************************************************************************/
81609885543Smrg
81709885543Smrgstatic XF86VideoAdaptorPtr
81809885543SmrgSMI_SetupVideo(ScreenPtr pScreen)
81909885543Smrg{
82009885543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
82109885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
82209885543Smrg    SMI_PortPtr smiPortPtr;
82309885543Smrg    XF86VideoAdaptorPtr ptrAdaptor;
82409885543Smrg
8257104f784Smrg    ENTER();
82609885543Smrg
82709885543Smrg    ptrAdaptor = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
82809885543Smrg		 sizeof(DevUnion) + sizeof(SMI_PortRec));
8297104f784Smrg    if (ptrAdaptor == NULL)
8307104f784Smrg	LEAVE(NULL);
83109885543Smrg
83209885543Smrg    ptrAdaptor->type = XvInputMask
83309885543Smrg#if SMI_USE_CAPTURE
83409885543Smrg		     | XvOutputMask
83509885543Smrg		     | XvVideoMask
83609885543Smrg#endif
83709885543Smrg		     | XvImageMask
83809885543Smrg		     | XvWindowMask
83909885543Smrg		     ;
84009885543Smrg
8417104f784Smrg    ptrAdaptor->flags = VIDEO_OVERLAID_IMAGES;
8427104f784Smrg    if (IS_MSOC(pSmi)) {
8437104f784Smrg	ptrAdaptor->name = "Silicon Motion MSOC Series Video Engine";
8447104f784Smrg    }
8457104f784Smrg    else
8467104f784Smrg	ptrAdaptor->name = "Silicon Motion Lynx Series Video Engine";
84709885543Smrg
84809885543Smrg    ptrAdaptor->nPorts = 1;
84909885543Smrg    ptrAdaptor->pPortPrivates = (DevUnion*) &ptrAdaptor[1];
85009885543Smrg    ptrAdaptor->pPortPrivates[0].ptr = (pointer) &ptrAdaptor->pPortPrivates[1];
85109885543Smrg
85209885543Smrg    smiPortPtr = (SMI_PortPtr) ptrAdaptor->pPortPrivates[0].ptr;
85309885543Smrg
85409885543Smrg    SMI_BuildEncodings(smiPortPtr);
85509885543Smrg    ptrAdaptor->nEncodings = smiPortPtr->nenc;
85609885543Smrg    ptrAdaptor->pEncodings = smiPortPtr->enc;
85709885543Smrg#if 0
85809885543Smrg    /* aaa whats this? */
85909885543Smrg	for (i = 0; i < nElems(SMI_VideoEncodings); i++)
86009885543Smrg	{
86109885543Smrg		SMI_VideoEncodings[i].width = pSmi->lcdWidth;
86209885543Smrg		SMI_VideoEncodings[i].height = pSmi->lcdHeight;
86309885543Smrg	}
86409885543Smrg#endif
86509885543Smrg
86609885543Smrg    ptrAdaptor->nFormats = nElems(SMI_VideoFormats);
86709885543Smrg    ptrAdaptor->pFormats = SMI_VideoFormats;
86809885543Smrg
86909885543Smrg    ptrAdaptor->nAttributes = nElems(SMI_VideoAttributes);
87009885543Smrg    ptrAdaptor->pAttributes = SMI_VideoAttributes;
87109885543Smrg
8727104f784Smrg    if (IS_MSOC(pSmi)) {
8737104f784Smrg	ptrAdaptor->nImages = nElems(SMI501_VideoImages);
8747104f784Smrg	ptrAdaptor->pImages = SMI501_VideoImages;
8757104f784Smrg    }
8767104f784Smrg    else {
8777104f784Smrg	ptrAdaptor->nImages = nElems(SMI_VideoImages);
8787104f784Smrg	ptrAdaptor->pImages = SMI_VideoImages;
8797104f784Smrg    }
88009885543Smrg
88109885543Smrg#if SMI_USE_CAPTURE
8827104f784Smrg    if (pSmi->Chipset == SMI_COUGAR3DR || IS_MSOC(pSmi))
88309885543Smrg	ptrAdaptor->PutVideo = NULL;
88409885543Smrg    else
88509885543Smrg	ptrAdaptor->PutVideo = SMI_PutVideo;
88609885543Smrg    ptrAdaptor->PutStill = NULL;
88709885543Smrg    ptrAdaptor->GetVideo = NULL;
88809885543Smrg    ptrAdaptor->GetStill = NULL;
88909885543Smrg#else
89009885543Smrg    ptrAdaptor->PutVideo = NULL;
89109885543Smrg    ptrAdaptor->PutStill = NULL;
89209885543Smrg    ptrAdaptor->GetVideo = NULL;
89309885543Smrg    ptrAdaptor->GetStill = NULL;
89409885543Smrg#endif
89509885543Smrg    ptrAdaptor->StopVideo = SMI_StopVideo;
89609885543Smrg    ptrAdaptor->SetPortAttribute = SMI_SetPortAttribute;
89709885543Smrg    ptrAdaptor->GetPortAttribute = SMI_GetPortAttribute;
89809885543Smrg    ptrAdaptor->QueryBestSize = SMI_QueryBestSize;
89909885543Smrg    ptrAdaptor->PutImage = SMI_PutImage;
90009885543Smrg    ptrAdaptor->QueryImageAttributes = SMI_QueryImageAttributes;
90109885543Smrg
90209885543Smrg    smiPortPtr->Attribute[XV_COLORKEY] = pSmi->videoKey;
90309885543Smrg    smiPortPtr->Attribute[XV_INTERLACED] = pSmi->interlaced;
90409885543Smrg    smiPortPtr->videoStatus = 0;
90509885543Smrg
90609885543Smrg#if 0
90709885543Smrg    /* aaa does not work ? */
90809885543Smrg    if (xf86I2CProbeAddress(pSmi->I2C, SAA7111))
9097104f784Smrg        LEAVE(NULL);
9107104f784Smrg    DEBUG("SAA7111 detected\n");
91109885543Smrg#endif
91209885543Smrg
91309885543Smrg    smiPortPtr->I2CDev.DevName = "SAA 7111A";
91409885543Smrg    smiPortPtr->I2CDev.SlaveAddr = SAA7111;
91509885543Smrg    smiPortPtr->I2CDev.pI2CBus = pSmi->I2C;
91609885543Smrg
9177104f784Smrg
9187104f784Smrg    if (!IS_MSOC(pSmi) && xf86I2CDevInit(&(smiPortPtr->I2CDev))) {
91909885543Smrg
92009885543Smrg	if (xf86I2CWriteVec(&(smiPortPtr->I2CDev), SAA7111InitData, ENTRIES(SAA7111InitData) / 2)) {
92109885543Smrg	    xvEncoding   = MAKE_ATOM(XV_ENCODING_NAME);
92209885543Smrg	    xvHue        = MAKE_ATOM(XV_HUE_NAME);
92309885543Smrg	    xvSaturation = MAKE_ATOM(XV_SATURATION_NAME);
92409885543Smrg	    xvContrast   = MAKE_ATOM(XV_CONTRAST_NAME);
92509885543Smrg
92609885543Smrg	    xvInterlaced = MAKE_ATOM(XV_INTERLACED_NAME);
9277104f784Smrg	    DEBUG("SAA7111 intialized\n");
92809885543Smrg
92909885543Smrg	} else {
93009885543Smrg	    xf86DestroyI2CDevRec(&(smiPortPtr->I2CDev),FALSE);
93109885543Smrg	    smiPortPtr->I2CDev.SlaveAddr = 0;
93209885543Smrg	}
93309885543Smrg    } else
93409885543Smrg	smiPortPtr->I2CDev.SlaveAddr = 0;
93509885543Smrg
93609885543Smrg#if defined(REGION_NULL)
93709885543Smrg    REGION_NULL(pScreen, &smiPortPtr->clip);
93809885543Smrg#else
93909885543Smrg    REGION_INIT(pScreen, &smiPortPtr->clip, NullBox, 0);
94009885543Smrg#endif
94109885543Smrg
94209885543Smrg    pSmi->ptrAdaptor = ptrAdaptor;
94309885543Smrg    pSmi->BlockHandler = pScreen->BlockHandler;
94409885543Smrg    pScreen->BlockHandler = SMI_BlockHandler;
94509885543Smrg
94609885543Smrg    xvColorKey   = MAKE_ATOM(XV_COLORKEY_NAME);
94709885543Smrg    xvBrightness = MAKE_ATOM(XV_BRIGHTNESS_NAME);
94809885543Smrg    xvCapBrightness = MAKE_ATOM(XV_CAPTURE_BRIGHTNESS_NAME);
94909885543Smrg
95009885543Smrg    SMI_ResetVideo(pScrn);
9517104f784Smrg
9527104f784Smrg    LEAVE(ptrAdaptor);
95309885543Smrg}
95409885543Smrg
95509885543Smrg
95609885543Smrgstatic void
95709885543SmrgSMI_ResetVideo(ScrnInfoPtr pScrn)
95809885543Smrg{
95909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
96009885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
96109885543Smrg    int r, g, b;
96209885543Smrg
9637104f784Smrg    ENTER();
96409885543Smrg
96509885543Smrg    SetAttr(pScrn, XV_ENCODING, 0);     /* Encoding = pal-composite-0 */
96609885543Smrg    SetAttr(pScrn, XV_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */
96709885543Smrg    SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */
96809885543Smrg    SetAttr(pScrn, XV_CONTRAST, 71);    /* Contrast = 71 (CCIR level) */
96909885543Smrg    SetAttr(pScrn, XV_SATURATION, 64);  /* Color saturation = 64 (CCIR level) */
97009885543Smrg    SetAttr(pScrn, XV_HUE, 0);          /* Hue = 0 */
97109885543Smrg
97209885543Smrg    switch (pScrn->depth) {
97309885543Smrg    case 8:
97409885543Smrg	SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0x00FF);
97509885543Smrg	SetKeyReg(pSmi, FPR08, 0);
97609885543Smrg	break;
97709885543Smrg    case 15:
97809885543Smrg    case 16:
97909885543Smrg	SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0xFFFF);
98009885543Smrg	SetKeyReg(pSmi, FPR08, 0);
98109885543Smrg	break;
98209885543Smrg    default:
98309885543Smrg        r = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.red) >> pScrn->offset.red;
98409885543Smrg        g = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.green) >> pScrn->offset.green;
98509885543Smrg        b = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.blue) >> pScrn->offset.blue;
98609885543Smrg	SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3));
98709885543Smrg	SetKeyReg(pSmi, FPR08, 0);
98809885543Smrg	break;
98909885543Smrg    }
99009885543Smrg
99109885543Smrg    SetKeyReg(pSmi, FPR5C, 0xEDEDED | (pPort->Attribute[XV_BRIGHTNESS] << 24));
99209885543Smrg
9937104f784Smrg    LEAVE();
99409885543Smrg}
99509885543Smrg
99609885543Smrg
99709885543Smrg#if SMI_USE_CAPTURE
99809885543Smrgstatic int
99909885543SmrgSMI_PutVideo(
100009885543Smrg	ScrnInfoPtr	pScrn,
100109885543Smrg	short		vid_x,
100209885543Smrg	short		vid_y,
100309885543Smrg	short		drw_x,
100409885543Smrg	short		drw_y,
100509885543Smrg	short		vid_w,
100609885543Smrg	short		vid_h,
100709885543Smrg	short		drw_w,
100809885543Smrg	short		drw_h,
100909885543Smrg	RegionPtr	clipBoxes,
101009885543Smrg	pointer		data,
101109885543Smrg	DrawablePtr	pDraw
101209885543Smrg)
101309885543Smrg{
101409885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
101509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
101609885543Smrg    CARD32 vid_pitch, vid_address;
101709885543Smrg    CARD32 vpr00, cpr00;
101809885543Smrg    int xscale, yscale;
101909885543Smrg    BoxRec dstBox;
102009885543Smrg    INT32 x1, y1, x2, y2;
102109885543Smrg    int norm;
102209885543Smrg    int size, width, height, fbPitch;
102309885543Smrg    int top, left;
10247104f784Smrg    xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn);
10257104f784Smrg    xf86CrtcPtr crtc;
102609885543Smrg
10277104f784Smrg    ENTER();
102809885543Smrg
10297104f784Smrg    DEBUG("Interlaced Video %d\n", pPort->Attribute[XV_INTERLACED]);
103009885543Smrg
103109885543Smrg    if (!pPort->Attribute[XV_INTERLACED]) {
103209885543Smrg	/* no interlace: lines will be doubled */
103309885543Smrg	vid_h /= 2;
103409885543Smrg    }
103509885543Smrg
103609885543Smrg    /* field start aaa*/
103709885543Smrg    norm = pPort->norm[pPort->Attribute[XV_ENCODING]];
103809885543Smrg    vid_x += VideoNorms[norm].HStart;
103909885543Smrg    vid_y += VideoNorms[norm].VStart;
104009885543Smrg    /* only even values allowed (UV-phase) */
104109885543Smrg    vid_x &= ~1;
104209885543Smrg
10437104f784Smrg    DEBUG("vid_x=%d vid_y=%d drw_x=%d drw_y=%d  "
10447104f784Smrg	  "vid_w=%d vid_h=%d drw_w=%d drw_h=%d\n",
10457104f784Smrg	  vid_x, vid_y, drw_x, drw_y, vid_w, vid_h, drw_w, drw_h);
104609885543Smrg
104709885543Smrg    x1 = vid_x;
104809885543Smrg    y1 = vid_y;
104909885543Smrg    x2 = vid_x + vid_w;
105009885543Smrg    y2 = vid_y + vid_h;
105109885543Smrg
105209885543Smrg    width = vid_w;
105309885543Smrg    height = vid_h;
105409885543Smrg
105509885543Smrg    dstBox.x1 = drw_x;
105609885543Smrg    dstBox.y1 = drw_y;
105709885543Smrg    dstBox.x2 = drw_x + drw_w;
105809885543Smrg    dstBox.y2 = drw_y + drw_h;
105909885543Smrg
10607104f784Smrg    if(!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
10617104f784Smrg	LEAVE(Success);
10627104f784Smrg
10637104f784Smrg    if(pSmi->Dualhead && crtc == crtcConf->crtc[1])
10647104f784Smrg	LEAVE(Success);
106509885543Smrg
10667104f784Smrg    /* Transform dstBox to the CRTC coordinates */
10677104f784Smrg    dstBox.x1 -= crtc->x;
10687104f784Smrg    dstBox.y1 -= crtc->y;
10697104f784Smrg    dstBox.x2 -= crtc->x;
10707104f784Smrg    dstBox.y2 -= crtc->y;
107109885543Smrg
10727104f784Smrg    DEBUG("Clip: x1=%d y1=%d x2=%d y2=%d\n",  x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16);
107309885543Smrg
107409885543Smrg    vid_pitch = (vid_w * 2 + 7) & ~7;
107509885543Smrg
107609885543Smrg    vpr00 = READ_VPR(pSmi, 0x00) & ~0x0FF000FF;
107709885543Smrg    cpr00 = READ_CPR(pSmi, 0x00) & ~0x000FFF00;
107809885543Smrg
107909885543Smrg    /* vpr00:
108009885543Smrg       Bit 2..0   = 6: Video Window I Format                    = YUV4:2:2
108109885543Smrg       Bit 3      = 1: Video Window I Enable                    = enabled
108209885543Smrg       Bit 4      = 0: Video Window I YUV Averaging             = disabled
108309885543Smrg       Bit 5      = 0: Video Window I Hor. Replication          = disabled
108409885543Smrg       Bit 6      = 0: Video Window I data doubling             = disabled
108509885543Smrg       Bit 14..8  = 0: Video Window II                          = disabled
108609885543Smrg       Bit 18..16 = 0: Graphics Data Format                     = 8-bit index
108709885543Smrg       Bit 19     = 0: Top Video Window Select                  = window I
108809885543Smrg       Bit 20     = 1: Color Key for Window I                   = enabled
108909885543Smrg       Bit 21     = 0: Vertical Interpolation                   = s. below
109009885543Smrg       Bit 22     = 0: Flicker Reduction for TV Modes           = disabled
109109885543Smrg       Bit 23     = 0: Fixed Vertical Interpolation             = disabled
109209885543Smrg       Bit 24     = 1: Select Video Window I Source Addr        =
109309885543Smrg       Bit 25     = 0: Enable V0FIFO to fetch 8-Bit color data  = disabled
109409885543Smrg       Bit 26     = 0:
109509885543Smrg       Bit 27     = 1: Color Key for Window II                  = disabled
109609885543Smrg       Bit 31..28 = reserved
109709885543Smrg    */
109809885543Smrg    if (pPort->Attribute[XV_INTERLACED]) {
109909885543Smrg	/*
110009885543Smrg	  Bit 21     = 0: Vertical Interpolation                   = disabled
110109885543Smrg	  Bit 24     = 0: Select Video Window I Source Addr        = 0
110209885543Smrg	*/
110309885543Smrg	vpr00 |= 0x0010000E;
110409885543Smrg    } else {
110509885543Smrg	/*
1106e4f6584cSmrg	  Bit 21     = 1: Vertical Interpolation                   = enabled
110709885543Smrg	  Bit 24     = 1: Select Video Window I Source Addr        = 1
110809885543Smrg	  1= Video window I source addr = capture port buffer ?
110909885543Smrg	*/
111009885543Smrg	vpr00 |= 0x0130000E;
111109885543Smrg    }
111209885543Smrg
111309885543Smrg    /* cpr00:
111409885543Smrg       Bit 0      = 1: Video Capture Enable                     = enabled
111509885543Smrg       Bit 8      = 0: Capture Control                          = continous
111609885543Smrg       Bit 9      = 0: Double Buffer Enable                     = s. below
111709885543Smrg       Bit 10     = 0: Interlace Data Capture                   = s. below
111809885543Smrg       Bit 13..11 = 0: Frame Skip Enable                        = s. below
111909885543Smrg       Bit 15..14 = 0: Video Capture Input Format               = YUV4:2:2
112009885543Smrg       Bit 17..16 = 0: Enable Hor. Reduction                    = s. below
112109885543Smrg       Bit 19..18 = 0: Enable Vert. Reduction                   = s. below
112209885543Smrg       Bit 21..20 = 0: Enable Hor. Filtering                    = s. below
112309885543Smrg       Bit 22     = 0: HREF Polarity                            = high active
112409885543Smrg       Bit 23     = 0: VREF Polarity                            = high active
112509885543Smrg       Bit 24     = 1: Field Detection Method VSYNC edge        = rising
112609885543Smrg    */
112709885543Smrg    if (pPort->Attribute[XV_INTERLACED]) {
112809885543Smrg	/*
112909885543Smrg	  Bit 9      = 1: Double Buffer Enable                  = enabled
113009885543Smrg	  Bit 10     = 1: Interlace Data Capture                = enabled
113109885543Smrg	  Bit 13..11 = 0: Frame Skip Enable                     = no skip
113209885543Smrg	*/
113309885543Smrg	cpr00 |= 0x01000601;
113409885543Smrg    } else {
113509885543Smrg	/*
113609885543Smrg	  Bit 9      = 0: Double Buffer Enable                  = disabled
113709885543Smrg	  Bit 10     = 0: Interlace Data Capture                = disabled
113809885543Smrg	  Bit 13..11 = 010: Frame Skip Enable                   = skip every other frame
113909885543Smrg	*/
11407104f784Smrg	cpr00 |= 0x01001001;
114109885543Smrg    }
114209885543Smrg
114309885543Smrg    if (pSmi->ByteSwap)
114409885543Smrg	cpr00 |= 0x00004000;
114509885543Smrg
11467104f784Smrg    fbPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15;
114709885543Smrg
114809885543Smrg    if (vid_w <= drw_w) {
114909885543Smrg	xscale = (256 * vid_w / drw_w) & 0xFF;
115009885543Smrg    } else if (vid_w / 2 <= drw_w) {
115109885543Smrg	xscale = (128 * vid_w / drw_w) & 0xFF;
115209885543Smrg	width /= 2;
115309885543Smrg	vid_pitch /= 2;
115409885543Smrg	cpr00 |= 0x00010000;
115509885543Smrg    } else if (vid_w / 4 <= drw_w) {
115609885543Smrg	xscale = (64 * vid_w / drw_w) & 0xFF;
115709885543Smrg	width /= 4;
115809885543Smrg	vid_pitch /= 4;
115909885543Smrg	cpr00 |= 0x00020000;
116009885543Smrg    } else {
116109885543Smrg	xscale = 0;
116209885543Smrg	width /= 4;
116309885543Smrg	vid_pitch /= 4;
116409885543Smrg	cpr00 |= 0x00020000;
116509885543Smrg    }
116609885543Smrg
116709885543Smrg    if (vid_h <= drw_h) {
116809885543Smrg	yscale = (256 * vid_h / drw_h) & 0xFF;
116909885543Smrg    } else if (vid_h / 2 <= drw_h) {
117009885543Smrg	yscale = (128 * vid_h / drw_h) & 0xFF;
117109885543Smrg	height /= 2;
117209885543Smrg	cpr00 |= 0x00040000;
117309885543Smrg    } else if (vid_h / 4 <= drw_h) {
117409885543Smrg	yscale = (64 * vid_h / drw_h) & 0xFF;
117509885543Smrg	height /= 4;
117609885543Smrg	cpr00 |= 0x00080000;
117709885543Smrg    } else {
117809885543Smrg	yscale = 0;
117909885543Smrg	height /= 4;
118009885543Smrg	cpr00 |= 0x00080000;
118109885543Smrg    }
118209885543Smrg
118309885543Smrg    do {
118409885543Smrg	size = vid_pitch * height;
11857104f784Smrg	DEBUG("SMI_AllocateMemory: vid_pitch=%d height=%d size=%d\n",
11867104f784Smrg	      vid_pitch, height, size);
118709885543Smrg	pPort->video_offset = SMI_AllocateMemory(pScrn, &pPort->video_memory, size);
118809885543Smrg        if (pPort->video_offset == 0) {
118909885543Smrg	    if ((cpr00 & 0x000C0000) == 0) {
119009885543Smrg		/* height -> 1/2 height */
119109885543Smrg		yscale = (128 * vid_h / drw_h) & 0xFF;
119209885543Smrg		height = vid_h / 2;
119309885543Smrg		cpr00 |= 0x00040000;
119409885543Smrg	    } else if (cpr00 & 0x00040000) {
119509885543Smrg		/* 1/2 height -> 1/4 height */
119609885543Smrg		yscale = (64 * vid_h / drw_h) & 0xFF;
119709885543Smrg		height = vid_h / 4;
119809885543Smrg		cpr00 ^= 0x000C0000;
119909885543Smrg	    } else {
120009885543Smrg		/* 1/4 height */
120109885543Smrg		if ((cpr00 & 0x00030000) == 0) {
120209885543Smrg		    /* width -> 1/2 width */
120309885543Smrg		    xscale = (128 * vid_w / drw_w) & 0xFF;
120409885543Smrg		    width = vid_w / 2;
120509885543Smrg		    cpr00 |= 0x00010000;
120609885543Smrg		} else if (cpr00 & 0x00010000) {
120709885543Smrg		    /* 1/2 width -> 1/4 width */
120809885543Smrg		    xscale = (64 * vid_w / drw_w) & 0xFF;
120909885543Smrg		    width = vid_w / 4;
121009885543Smrg		    cpr00 ^= 0x00030000;
121109885543Smrg		} else {
12127104f784Smrg		    DEBUG("allocate error\n");
12137104f784Smrg		    LEAVE(BadAlloc);
121409885543Smrg		}
121509885543Smrg	    }
121609885543Smrg	}
121709885543Smrg    } while (pPort->video_offset == 0);
121809885543Smrg
12197104f784Smrg    DEBUG("xscale==%d yscale=%d width=%d height=%d\n",
12207104f784Smrg	  xscale, yscale, width, height);
122109885543Smrg
122209885543Smrg    /* aaa whats this                     ----------------------v ?
122309885543Smrg    vid_address = (pPort->area->box.y1 * fbPitch) + ((y1 >> 16) * vid_pitch);*/
122409885543Smrg    vid_address = pPort->video_offset;
122509885543Smrg
12267104f784Smrg    DEBUG("test RegionsEqual\n");
122709885543Smrg    if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes))
122809885543Smrg    {
122909885543Smrg	DEBUG((VERBLEV, "RegionCopy\n"));
123009885543Smrg        REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes);
12317104f784Smrg	DEBUG("FillKey\n");
123209885543Smrg	xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes);
123309885543Smrg
123409885543Smrg    }
123509885543Smrg
123609885543Smrg    left = x1 >> 16;
123709885543Smrg    top = y1 >> 16;
123809885543Smrg    width = (x2 - x1) >> 16;
123909885543Smrg    height = (y2 - y1) >> 16;
124009885543Smrg
12417104f784Smrg    if (!IS_MSOC(pSmi))
12427104f784Smrg	VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA,
12437104f784Smrg		      0x21,
12447104f784Smrg		      VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA,
12457104f784Smrg				   0x21) & ~0x04);
124609885543Smrg    WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) | 0x00200000);
124709885543Smrg    /* Video Window I Left and Top Boundaries */
124809885543Smrg    WRITE_VPR(pSmi, 0x14, dstBox.x1 + (dstBox.y1 << 16));
124909885543Smrg    /* Video Window I Right and Bottom Boundaries */
125009885543Smrg    WRITE_VPR(pSmi, 0x18, dstBox.x2 + (dstBox.y2 << 16));
125109885543Smrg    /* Video Window I Source Width and Offset */
125209885543Smrg    WRITE_VPR(pSmi, 0x20, (vid_pitch / 8) + ((vid_pitch / 8) << 16));
125309885543Smrg    /* Video Window I Stretch Factor */
125409885543Smrg    WRITE_VPR(pSmi, 0x24, (xscale << 8) + yscale);
125509885543Smrg
125609885543Smrg    if (pPort->Attribute[XV_INTERLACED]) {
125709885543Smrg	/* Video Window II Left and Top Boundaries */
125809885543Smrg	WRITE_VPR(pSmi, 0x28, dstBox.x1 + (dstBox.y1 << 16));
125909885543Smrg	/* Video Window II Right and Bottom Boundaries */
126009885543Smrg	WRITE_VPR(pSmi, 0x2C, dstBox.x2 + (dstBox.y2 << 16));
126109885543Smrg	/* Video Window II Source Width and Offset */
126209885543Smrg	WRITE_VPR(pSmi, 0x34, (vid_pitch / 8) + ((vid_pitch / 8) << 16));
126309885543Smrg	/* Video Window II Stretch Factor */
126409885543Smrg	WRITE_VPR(pSmi, 0x38, (xscale << 8) + yscale);
126509885543Smrg
126609885543Smrg	/* Video Window I Source Start Address */
126709885543Smrg	WRITE_VPR(pSmi, 0x1C, vid_address / 8);
126809885543Smrg	/* Video Window II Source Start Address */
126909885543Smrg	WRITE_VPR(pSmi, 0x30, vid_address / 8);
127009885543Smrg
127109885543Smrg	/* Video Window I Source Start Address */
127209885543Smrg	WRITE_VPR(pSmi, 0x48, vid_address / 8);
127309885543Smrg	/* Video Window II Source Start Address */
127409885543Smrg	WRITE_VPR(pSmi, 0x4C, vid_address / 8 + vid_pitch / 8);
127509885543Smrg
127609885543Smrg	/* Video Source Clipping Control */
127709885543Smrg	WRITE_CPR(pSmi, 0x04, left + ((top/2) << 16));
127809885543Smrg	/* Video Source Capture Size Control */
127909885543Smrg	WRITE_CPR(pSmi, 0x08, width + ((height/2) << 16));
128009885543Smrg	/* Capture Port Buffer I Source Start Address */
128109885543Smrg	WRITE_CPR(pSmi, 0x0C, vid_address / 8);
128209885543Smrg	/* Capture Port Buffer II Source Start Address */
128309885543Smrg	WRITE_CPR(pSmi, 0x10, vid_address / 8 + vid_pitch / 8);
128409885543Smrg	/* Capture Port Source Offset Address */
128509885543Smrg	WRITE_CPR(pSmi, 0x14, 2*(vid_pitch / 8) + ((2*(vid_pitch / 8)) << 16));
128609885543Smrg    } else {
128709885543Smrg	/* Video Source Clipping Control */
128809885543Smrg	WRITE_CPR(pSmi, 0x04, left + (top << 16));
128909885543Smrg	/* Video Source Capture Size Control */
129009885543Smrg	WRITE_CPR(pSmi, 0x08, width + (height << 16));
129109885543Smrg	/* Capture Port Buffer I Source Start Address */
129209885543Smrg	WRITE_CPR(pSmi, 0x0C, vid_address / 8);
129309885543Smrg	/* Capture Port Buffer II Source Start Address */
129409885543Smrg	WRITE_CPR(pSmi, 0x10, vid_address / 8);
129509885543Smrg	/* Capture Port Source Offset Address */
129609885543Smrg	WRITE_CPR(pSmi, 0x14, (vid_pitch / 8) + ((vid_pitch / 8) << 16));
129709885543Smrg    }
129809885543Smrg
129909885543Smrg    WRITE_CPR(pSmi, 0x00, cpr00);
130009885543Smrg    WRITE_VPR(pSmi, 0x00, vpr00);
130109885543Smrg
130209885543Smrg    pPort->videoStatus = CLIENT_VIDEO_ON;
13037104f784Smrg    DEBUG("SMI_PutVideo success\n");
13047104f784Smrg
13057104f784Smrg    LEAVE(Success);
130609885543Smrg}
130709885543Smrg#endif
130809885543Smrg
130909885543Smrg
131009885543Smrgstatic void
131109885543SmrgSMI_StopVideo(
131209885543Smrg	ScrnInfoPtr	pScrn,
131309885543Smrg	pointer		data,
131409885543Smrg	Bool		shutdown
131509885543Smrg)
131609885543Smrg{
131709885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
131809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
131909885543Smrg
13207104f784Smrg    ENTER();
132109885543Smrg
132209885543Smrg    REGION_EMPTY(pScrn->pScreen, &pPort->clip);
132309885543Smrg
132409885543Smrg    if (shutdown) {
132509885543Smrg	if (pPort->videoStatus & CLIENT_VIDEO_ON) {
13267104f784Smrg	    if (pSmi->Chipset == SMI_COUGAR3DR)
132709885543Smrg		WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE));
13287104f784Smrg	    else if (IS_MSOC(pSmi))
13297104f784Smrg		WRITE_DCR(pSmi, 0x0040, READ_DCR(pSmi, 0x0040) & ~0x00000004);
13307104f784Smrg	    else
133109885543Smrg		WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x01000008);
133209885543Smrg#if SMI_USE_CAPTURE
13337104f784Smrg	    if (!IS_MSOC(pSmi) && pSmi->Chipset != SMI_COUGAR3DR) {
133409885543Smrg		WRITE_CPR(pSmi, 0x00, READ_CPR(pSmi, 0x00) & ~0x00000001);
133509885543Smrg		WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) & ~0x00F00000);
133609885543Smrg	    }
133709885543Smrg#endif
133809885543Smrg	}
133909885543Smrg        if (pPort->video_memory != NULL) {
134009885543Smrg            SMI_FreeMemory(pScrn, pPort->video_memory);
134109885543Smrg            pPort->video_memory = NULL;
134209885543Smrg	}
134309885543Smrg        pPort->videoStatus = 0;
134409885543Smrg        /* pPort->i2cDevice = 0;aaa*/
134509885543Smrg    } else {
134609885543Smrg        if (pPort->videoStatus & CLIENT_VIDEO_ON) {
134709885543Smrg            pPort->videoStatus |= OFF_TIMER;
134809885543Smrg            pPort->offTime = currentTime.milliseconds + OFF_DELAY;
134909885543Smrg	}
135009885543Smrg    }
135109885543Smrg
13527104f784Smrg    LEAVE();
135309885543Smrg}
135409885543Smrg
135509885543Smrgstatic int
135609885543SmrgSMI_SetPortAttribute(
135709885543Smrg	ScrnInfoPtr	pScrn,
135809885543Smrg	Atom		attribute,
135909885543Smrg	INT32		value,
136009885543Smrg	pointer		data
136109885543Smrg)
136209885543Smrg{
136309885543Smrg    int res;
136409885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
136509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
136609885543Smrg
13677104f784Smrg    ENTER();
136809885543Smrg
136909885543Smrg    if (attribute == xvColorKey) {
137009885543Smrg	int r, g, b;
137109885543Smrg
137209885543Smrg        pPort->Attribute[XV_COLORKEY] = value;
137309885543Smrg	switch (pScrn->depth) {
137409885543Smrg	case 8:
137509885543Smrg	    SetKeyReg(pSmi, FPR04, value & 0x00FF);
137609885543Smrg	    break;
137709885543Smrg	case 15:
137809885543Smrg	case 16:
137909885543Smrg	    SetKeyReg(pSmi, FPR04, value & 0xFFFF);
138009885543Smrg	    break;
138109885543Smrg	default:
138209885543Smrg	    r = (value & pScrn->mask.red) >> pScrn->offset.red;
138309885543Smrg	    g = (value & pScrn->mask.green) >> pScrn->offset.green;
138409885543Smrg	    b = (value & pScrn->mask.blue) >> pScrn->offset.blue;
138509885543Smrg	    SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3));
138609885543Smrg	    break;
138709885543Smrg	}
138809885543Smrg	res = Success;
138909885543Smrg    } else if (attribute == xvInterlaced) {
139009885543Smrg        pPort->Attribute[XV_INTERLACED] = (value != 0);
139109885543Smrg	res = Success;
139209885543Smrg    } else if (attribute == xvEncoding) {
139309885543Smrg        res = SetAttr(pScrn, XV_ENCODING, value);
139409885543Smrg    } else if (attribute == xvBrightness) {
139509885543Smrg        res = SetAttr(pScrn, XV_BRIGHTNESS, value);
139609885543Smrg    } else if (attribute == xvCapBrightness) {
139709885543Smrg        res = SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, value);
139809885543Smrg    } else if (attribute == xvContrast) {
139909885543Smrg        res = SetAttr(pScrn, XV_CONTRAST, value);
140009885543Smrg    } else if (attribute == xvSaturation) {
140109885543Smrg        res = SetAttr(pScrn, XV_SATURATION, value);
140209885543Smrg    } else if (attribute == xvHue) {
140309885543Smrg        res = SetAttr(pScrn, XV_HUE, value);
140409885543Smrg    } else {
140509885543Smrg        res = BadMatch;
140609885543Smrg    }
140709885543Smrg
14087104f784Smrg    LEAVE(res);
140909885543Smrg}
141009885543Smrg
141109885543Smrg
141209885543Smrgstatic int
141309885543SmrgSMI_GetPortAttribute(
141409885543Smrg	ScrnInfoPtr	pScrn,
141509885543Smrg	Atom		attribute,
141609885543Smrg	INT32		*value,
141709885543Smrg	pointer		data
141809885543Smrg)
141909885543Smrg{
142009885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
142109885543Smrg
14227104f784Smrg    ENTER();
142309885543Smrg    if (attribute == xvEncoding)
142409885543Smrg        *value = pPort->Attribute[XV_ENCODING];
142509885543Smrg    else if (attribute == xvBrightness)
142609885543Smrg        *value = pPort->Attribute[XV_BRIGHTNESS];
142709885543Smrg    else if (attribute == xvCapBrightness)
142809885543Smrg        *value = pPort->Attribute[XV_CAPTURE_BRIGHTNESS];
142909885543Smrg    else if (attribute == xvContrast)
143009885543Smrg        *value = pPort->Attribute[XV_CONTRAST];
143109885543Smrg    else if (attribute == xvSaturation)
143209885543Smrg        *value = pPort->Attribute[XV_SATURATION];
143309885543Smrg    else if (attribute == xvHue)
143409885543Smrg        *value = pPort->Attribute[XV_HUE];
143509885543Smrg    else if (attribute == xvColorKey)
143609885543Smrg        *value = pPort->Attribute[XV_COLORKEY];
14377104f784Smrg    else
14387104f784Smrg	LEAVE(BadMatch);
143909885543Smrg
14407104f784Smrg    LEAVE(Success);
144109885543Smrg}
144209885543Smrg
144309885543Smrg
144409885543Smrgstatic void
144509885543SmrgSMI_QueryBestSize(
144609885543Smrg	ScrnInfoPtr		pScrn,
144709885543Smrg	Bool			motion,
144809885543Smrg	short			vid_w,
144909885543Smrg	short			vid_h,
145009885543Smrg	short			drw_w,
145109885543Smrg	short			drw_h,
145209885543Smrg	unsigned int	*p_w,
145309885543Smrg	unsigned int	*p_h,
145409885543Smrg	pointer			data
145509885543Smrg)
145609885543Smrg{
145709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
145809885543Smrg
14597104f784Smrg    ENTER();
146009885543Smrg
146109885543Smrg    *p_w = min(drw_w, pSmi->lcdWidth);
146209885543Smrg    *p_h = min(drw_h, pSmi->lcdHeight);
146309885543Smrg
14647104f784Smrg    LEAVE();
146509885543Smrg}
146609885543Smrg
146709885543Smrg
146809885543Smrgstatic int
146909885543SmrgSMI_PutImage(
147009885543Smrg	ScrnInfoPtr		pScrn,
147109885543Smrg	short			src_x,
147209885543Smrg	short			src_y,
147309885543Smrg	short			drw_x,
147409885543Smrg	short			drw_y,
147509885543Smrg	short			src_w,
147609885543Smrg	short			src_h,
147709885543Smrg	short			drw_w,
147809885543Smrg	short			drw_h,
14797104f784Smrg	int			id,
14807104f784Smrg	unsigned char		*buf,
148109885543Smrg	short			width,
148209885543Smrg	short			height,
148309885543Smrg	Bool			sync,
148409885543Smrg	RegionPtr		clipBoxes,
148509885543Smrg	pointer			data,
148609885543Smrg	DrawablePtr		pDraw
148709885543Smrg)
148809885543Smrg{
148909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
149009885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
149109885543Smrg    INT32 x1, y1, x2, y2;
149209885543Smrg    int bpp = 0;
149309885543Smrg    int srcPitch, srcPitch2 = 0, dstPitch, size;
149409885543Smrg    BoxRec dstBox;
149509885543Smrg    CARD32 offset, offset2 = 0, offset3 = 0, tmp;
149609885543Smrg    int left, top, nPixels, nLines;
149709885543Smrg    unsigned char *dstStart;
14987104f784Smrg    xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn);
14997104f784Smrg    xf86CrtcPtr crtc;
150009885543Smrg
15017104f784Smrg    ENTER();
150209885543Smrg
150309885543Smrg    x1 = src_x;
150409885543Smrg    y1 = src_y;
150509885543Smrg    x2 = src_x + src_w;
150609885543Smrg    y2 = src_y + src_h;
150709885543Smrg
150809885543Smrg    dstBox.x1 = drw_x;
150909885543Smrg    dstBox.y1 = drw_y;
151009885543Smrg    dstBox.x2 = drw_x + drw_w;
151109885543Smrg    dstBox.y2 = drw_y + drw_h;
151209885543Smrg
15137104f784Smrg    if (pSmi->CSCVideo) {
15147104f784Smrg	if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
15157104f784Smrg				   width, height))
15167104f784Smrg	    LEAVE(Success);
151709885543Smrg    }
15187104f784Smrg    else {
15197104f784Smrg	if (!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox,
15207104f784Smrg					 &x1, &x2, &y1, &y2, clipBoxes,
15217104f784Smrg					 width, height))
15227104f784Smrg	    LEAVE(Success);
152309885543Smrg
15247104f784Smrg	/* Transform dstBox to the CRTC coordinates */
15257104f784Smrg	dstBox.x1 -= crtc->x;
15267104f784Smrg	dstBox.y1 -= crtc->y;
15277104f784Smrg	dstBox.x2 -= crtc->x;
15287104f784Smrg	dstBox.y2 -= crtc->y;
15297104f784Smrg    }
153009885543Smrg
153109885543Smrg    switch (id) {
153209885543Smrg    case FOURCC_YV12:
15337104f784Smrg    case FOURCC_I420:
153409885543Smrg	srcPitch  = (width + 3) & ~3;
153509885543Smrg	offset2   = srcPitch * height;
153609885543Smrg	srcPitch2 = ((width >> 1) + 3) & ~3;
153709885543Smrg	offset3   = offset2 + (srcPitch2 * (height >> 1));
15387104f784Smrg	if (pSmi->CSCVideo)
15397104f784Smrg	    dstPitch  = (((width >> 1) + 15) & ~15) << 1;
15407104f784Smrg	else
15417104f784Smrg	    dstPitch  = ((width << 1) + 15) & ~15;
154209885543Smrg	break;
154309885543Smrg    case FOURCC_RV24:
154409885543Smrg	bpp = 3;
154509885543Smrg	srcPitch = width * bpp;
154609885543Smrg	dstPitch = (srcPitch + 15) & ~15;
154709885543Smrg	break;
154809885543Smrg    case FOURCC_RV32:
154909885543Smrg	bpp = 4;
155009885543Smrg	srcPitch = width * bpp;
155109885543Smrg	dstPitch = (srcPitch + 15) & ~15;
155209885543Smrg	break;
155309885543Smrg    case FOURCC_YUY2:
155409885543Smrg    case FOURCC_RV15:
155509885543Smrg    case FOURCC_RV16:
155609885543Smrg    default:
155709885543Smrg	bpp = 2;
155809885543Smrg	srcPitch = width * bpp;
155909885543Smrg	dstPitch = (srcPitch + 15) & ~15;
156009885543Smrg	break;
156109885543Smrg    }
156209885543Smrg
156309885543Smrg    size = dstPitch * height;
156409885543Smrg    pPort->video_offset = SMI_AllocateMemory(pScrn, &pPort->video_memory, size);
15657104f784Smrg    if (pPort->video_memory == NULL)
15667104f784Smrg	LEAVE(BadAlloc);
156709885543Smrg
156809885543Smrg    top = y1 >> 16;
156909885543Smrg    left = (x1 >> 16) & ~1;
157009885543Smrg    nPixels = ((((x2 + 0xFFFF) >> 16) + 1) & ~1) - left;
157109885543Smrg    left *= bpp;
157209885543Smrg
157309885543Smrg    offset = pPort->video_offset + (top * dstPitch);
157409885543Smrg    dstStart = pSmi->FBBase + offset + left;
157509885543Smrg
157609885543Smrg    switch(id) {
157709885543Smrg    case FOURCC_YV12:
157809885543Smrg    case FOURCC_I420:
157909885543Smrg	top &= ~1;
158009885543Smrg	tmp = ((top >> 1) * srcPitch2) + (left >> 2);
158109885543Smrg	offset2 += tmp;
158209885543Smrg	offset3 += tmp;
15837104f784Smrg	if (pSmi->CSCVideo)
15847104f784Smrg	    CopyYV12ToVideoMem(buf,
15857104f784Smrg			       buf + offset2, buf + offset3,
15867104f784Smrg			       dstStart, srcPitch, srcPitch2, dstPitch,
15877104f784Smrg			       height, width);
15887104f784Smrg	else {
15897104f784Smrg	    if (id == FOURCC_I420) {
15907104f784Smrg		tmp = offset2;
15917104f784Smrg		offset2 = offset3;
15927104f784Smrg		offset3 = tmp;
15937104f784Smrg	    }
15947104f784Smrg	    nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
15957104f784Smrg	    xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1),
15967104f784Smrg				    buf + offset2, buf + offset3, dstStart,
15977104f784Smrg				    srcPitch, srcPitch2, dstPitch, nLines,
15987104f784Smrg				    nPixels);
159909885543Smrg	}
160009885543Smrg	break;
160109885543Smrg    case FOURCC_UYVY:
160209885543Smrg    case FOURCC_YUY2:
160309885543Smrg    default:
160409885543Smrg	buf += (top * srcPitch) + left;
160509885543Smrg	nLines = ((y2 + 0xffff) >> 16) - top;
160609885543Smrg	xf86XVCopyPacked(buf, dstStart, srcPitch, dstPitch, nLines, nPixels);
160709885543Smrg        break;
160809885543Smrg    }
160909885543Smrg
16107104f784Smrg    if (IS_MSOC(pSmi) ||
16117104f784Smrg	!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) {
16127104f784Smrg	REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes);
16137104f784Smrg	if (!pSmi->CSCVideo)
16147104f784Smrg	    xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY],
16157104f784Smrg				clipBoxes);
161609885543Smrg    }
161709885543Smrg
16187104f784Smrg    if (pSmi->Chipset == SMI_COUGAR3DR)
161909885543Smrg	SMI_DisplayVideo0730(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2,
162009885543Smrg			     &dstBox, src_w, src_h, drw_w, drw_h);
16217104f784Smrg    else if (IS_MSOC(pSmi)) {
16227104f784Smrg	if (pSmi->CSCVideo)
16237104f784Smrg	    SMI_DisplayVideo0501_CSC(pScrn, id, offset, width, height, dstPitch,
16247104f784Smrg				     x1, y1, x2, y2, &dstBox,
16257104f784Smrg				     src_w, src_h, drw_w, drw_h, clipBoxes);
16267104f784Smrg	else
16277104f784Smrg	    SMI_DisplayVideo0501(pScrn, id, offset, width, height, dstPitch,
16287104f784Smrg				 x1, y1, x2, y2, &dstBox, src_w, src_h,
16297104f784Smrg				 drw_w, drw_h);
16307104f784Smrg    }
16317104f784Smrg    else{
16327104f784Smrg	if(crtc == crtcConf->crtc[0])
16337104f784Smrg	    SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2,
16347104f784Smrg			     &dstBox, src_w, src_h, drw_w, drw_h);
16357104f784Smrg    }
163609885543Smrg    pPort->videoStatus = CLIENT_VIDEO_ON;
16377104f784Smrg
16387104f784Smrg    LEAVE(Success);
163909885543Smrg
164009885543Smrg}
164109885543Smrg
164209885543Smrg
164309885543Smrgstatic int
164409885543SmrgSMI_QueryImageAttributes(
164509885543Smrg	ScrnInfoPtr	pScrn,
164609885543Smrg	int		id,
164709885543Smrg	unsigned short	*width,
164809885543Smrg	unsigned short	*height,
164909885543Smrg	int		*pitches,
165009885543Smrg	int		*offsets
165109885543Smrg)
165209885543Smrg{
165309885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
165409885543Smrg    int size, tmp;
165509885543Smrg
16567104f784Smrg    ENTER();
165709885543Smrg
165809885543Smrg    if (*width > pSmi->lcdWidth) {
165909885543Smrg	*width = pSmi->lcdWidth;
166009885543Smrg    }
166109885543Smrg    if (*height > pSmi->lcdHeight) {
166209885543Smrg	*height = pSmi->lcdHeight;
166309885543Smrg    }
166409885543Smrg
166509885543Smrg    *width = (*width + 1) & ~1;
166609885543Smrg    if (offsets != NULL) {
166709885543Smrg	offsets[0] = 0;
166809885543Smrg    }
166909885543Smrg
167009885543Smrg    switch (id) {
167109885543Smrg    case FOURCC_YV12:
167209885543Smrg    case FOURCC_I420:
167309885543Smrg	*height = (*height + 1) & ~1;
167409885543Smrg	size = (*width + 3) & ~3;
167509885543Smrg	if (pitches != NULL) {
167609885543Smrg	    pitches[0] = size;
167709885543Smrg	}
167809885543Smrg	size *= *height;
167909885543Smrg	if (offsets != NULL) {
168009885543Smrg	    offsets[1] = size;
168109885543Smrg	}
168209885543Smrg	tmp = ((*width >> 1) + 3) & ~3;
168309885543Smrg	if (pitches != NULL) {
168409885543Smrg	    pitches[1] = pitches[2] = tmp;
168509885543Smrg	}
168609885543Smrg	tmp *= (*height >> 1);
168709885543Smrg	size += tmp;
168809885543Smrg	if (offsets != NULL) {
168909885543Smrg	    offsets[2] = size;
169009885543Smrg	}
169109885543Smrg	size += tmp;
169209885543Smrg	break;
169309885543Smrg    case FOURCC_YUY2:
169409885543Smrg    case FOURCC_RV15:
169509885543Smrg    case FOURCC_RV16:
169609885543Smrg    default:
169709885543Smrg	size = *width * 2;
169809885543Smrg	if (pitches != NULL) {
169909885543Smrg	    pitches[0] = size;
170009885543Smrg	}
170109885543Smrg	size *= *height;
170209885543Smrg	break;
170309885543Smrg    case FOURCC_RV24:
170409885543Smrg	size = *width * 3;
170509885543Smrg	if (pitches != NULL) {
170609885543Smrg	    pitches[0] = size;
170709885543Smrg	}
170809885543Smrg	size *= *height;
170909885543Smrg	break;
171009885543Smrg    case FOURCC_RV32:
171109885543Smrg	size = *width * 4;
171209885543Smrg	if (pitches != NULL) {
171309885543Smrg	    pitches[0] = size;
171409885543Smrg	}
171509885543Smrg	size *= *height;
171609885543Smrg	break;
171709885543Smrg    }
171809885543Smrg
17197104f784Smrg    LEAVE(size);
172009885543Smrg}
172109885543Smrg
172209885543Smrg
172309885543Smrg/******************************************************************************\
172409885543Smrg**									      **
172509885543Smrg**	S U P P O R T   F U N C T I O N S				      **
172609885543Smrg**									      **
172709885543Smrg\******************************************************************************/
172809885543Smrg
172909885543Smrgstatic void
173009885543SmrgSMI_DisplayVideo(
173109885543Smrg	ScrnInfoPtr	pScrn,
173209885543Smrg	int		id,
173309885543Smrg	int		offset,
173409885543Smrg	short		width,
173509885543Smrg	short		height,
173609885543Smrg	int		pitch,
173709885543Smrg	int		x1,
173809885543Smrg	int		y1,
173909885543Smrg	int		x2,
174009885543Smrg	int		y2,
174109885543Smrg	BoxPtr		dstBox,
174209885543Smrg	short		vid_w,
174309885543Smrg	short		vid_h,
174409885543Smrg	short		drw_w,
174509885543Smrg	short		drw_h
174609885543Smrg)
174709885543Smrg{
174809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
174909885543Smrg    CARD32 vpr00;
1750e4f6584cSmrg    uint32_t hstretch, vstretch;
175109885543Smrg
17527104f784Smrg    ENTER();
175309885543Smrg
175409885543Smrg    vpr00 = READ_VPR(pSmi, 0x00) & ~0x0CB800FF;
175509885543Smrg
175609885543Smrg    switch (id) {
175709885543Smrg    case FOURCC_YV12:
175809885543Smrg    case FOURCC_I420:
175909885543Smrg    case FOURCC_YUY2:
176009885543Smrg	vpr00 |= 0x6;
176109885543Smrg	break;
176209885543Smrg    case FOURCC_RV15:
176309885543Smrg	vpr00 |= 0x1;
176409885543Smrg	break;
176509885543Smrg    case FOURCC_RV16:
176609885543Smrg	vpr00 |= 0x2;
176709885543Smrg	break;
176809885543Smrg    case FOURCC_RV24:
176909885543Smrg	vpr00 |= 0x4;
177009885543Smrg	break;
177109885543Smrg    case FOURCC_RV32:
177209885543Smrg	vpr00 |= 0x3;
177309885543Smrg	break;
177409885543Smrg    }
177509885543Smrg
177609885543Smrg    if (drw_w > vid_w) {
1777e4f6584cSmrg	hstretch = ((uint32_t)(vid_w - 1) << 16) / (drw_w - 1);
177809885543Smrg    } else {
177909885543Smrg	hstretch = 0;
178009885543Smrg    }
178109885543Smrg
178209885543Smrg    if (drw_h > vid_h) {
1783e4f6584cSmrg	vstretch = ((uint32_t)(vid_h - 1) << 16) / (drw_h - 1);
178409885543Smrg	vpr00 |= 1 << 21;
178509885543Smrg    } else {
178609885543Smrg	vstretch = 0;
178709885543Smrg    }
17887104f784Smrg
178909885543Smrg    WRITE_VPR(pSmi, 0x00, vpr00 | (1 << 3) | (1 << 20));
179009885543Smrg    WRITE_VPR(pSmi, 0x14, (dstBox->x1) | (dstBox->y1 << 16));
179109885543Smrg    WRITE_VPR(pSmi, 0x18, (dstBox->x2) | (dstBox->y2 << 16));
179209885543Smrg    WRITE_VPR(pSmi, 0x1C, offset >> 3);
179309885543Smrg    WRITE_VPR(pSmi, 0x20, (pitch >> 3) | ((pitch >> 3) << 16));
1794e4f6584cSmrg    WRITE_VPR(pSmi, 0x24, (hstretch & 0xff00) | ((vstretch & 0xff00) >> 8));
1795e4f6584cSmrg    if (pSmi->Chipset == SMI_LYNXEMplus) {	/* This one can store additional precision */
1796e4f6584cSmrg	WRITE_VPR(pSmi, 0x68, ((hstretch & 0xff) << 8) | (vstretch & 0xff));
1797e4f6584cSmrg    }
179809885543Smrg
17997104f784Smrg    LEAVE();
18007104f784Smrg}
18017104f784Smrg
18027104f784Smrgstatic void
18037104f784SmrgSMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset,
18047104f784Smrg			 short width, short height, int pitch,
18057104f784Smrg			 int x1, int y1, int x2, int y2, BoxPtr dstBox,
18067104f784Smrg			 short vid_w, short vid_h, short drw_w, short drw_h,
18077104f784Smrg			 RegionPtr clipboxes)
18087104f784Smrg{
18097104f784Smrg    int32_t	ScaleXn, ScaleXd, ScaleYn, ScaleYd;
18107104f784Smrg    int32_t	SrcTn, SrcTd, SrcLn, SrcLd;
18117104f784Smrg    int32_t	SrcRn, SrcBn;
18127104f784Smrg    int32_t	SrcDimX, SrcDimY;
18137104f784Smrg    int32_t	SrcYBase, SrcUBase, SrcVBase, SrcYPitch, SrcUVPitch;
18147104f784Smrg    int32_t	DestPitch;
18157104f784Smrg    SMIPtr	pSmi = SMIPTR(pScrn);
18167104f784Smrg    BoxPtr	pbox = REGION_RECTS(clipboxes);
18177104f784Smrg    int		i, nbox = REGION_NUM_RECTS(clipboxes);
18187104f784Smrg    int32_t	rect_x, rect_y, rect_w, rect_h, csc;
18197104f784Smrg    float	Hscale, Vscale;
18207104f784Smrg
18217104f784Smrg    ENTER();
18227104f784Smrg
18237104f784Smrg    SrcYBase = offset;
18247104f784Smrg    SrcYPitch = pitch;
18257104f784Smrg
18267104f784Smrg    DestPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15;
18277104f784Smrg
18287104f784Smrg    Hscale = (vid_w - 1) / (float)(drw_w - 1);
18297104f784Smrg    ScaleXn = Hscale;
18307104f784Smrg    ScaleXd = ((vid_w - 1) << 13) / (drw_w - 1) - (ScaleXn << 13);
18317104f784Smrg
18327104f784Smrg    Vscale = (vid_h - 1) / (float)(drw_h - 1);
18337104f784Smrg    ScaleYn = Vscale;
18347104f784Smrg    ScaleYd = ((vid_h - 1) << 13) / (drw_h - 1) - (ScaleYn << 13);
18357104f784Smrg
18367104f784Smrg    /* CSC constants */
18377104f784Smrg    WRITE_DPR(pSmi, 0xcc, 0);
18387104f784Smrg    /* Use start of framebuffer as base offset */
18397104f784Smrg    WRITE_DPR(pSmi, 0xf8, 0);
18407104f784Smrg
18417104f784Smrg    csc = (1 << 31) | (1 << 25);
18427104f784Smrg    if (pSmi->Bpp > 2)
18437104f784Smrg	csc |= 1 << 26;
18447104f784Smrg
18457104f784Smrg    switch (id) {
18467104f784Smrg	case FOURCC_YV12:
18477104f784Smrg	    SrcUVPitch = SrcYPitch / 2;
18487104f784Smrg	    SrcVBase = SrcYBase + SrcYPitch * height;
18497104f784Smrg	    SrcUBase = SrcVBase + SrcUVPitch * height / 2;
18507104f784Smrg	    csc |= 2 << 28;
18517104f784Smrg	    break;
18527104f784Smrg
18537104f784Smrg	case FOURCC_I420:
18547104f784Smrg	    SrcUVPitch = SrcYPitch / 2;
18557104f784Smrg	    SrcUBase = SrcYBase + SrcYPitch * height;
18567104f784Smrg	    SrcVBase = SrcUBase + SrcUVPitch * height / 2;
18577104f784Smrg	    csc |= 2 << 28;
18587104f784Smrg	    break;
18597104f784Smrg
18607104f784Smrg	case FOURCC_YUY2:
18617104f784Smrg	case FOURCC_RV16:
18627104f784Smrg	case FOURCC_RV32:
18637104f784Smrg	    SrcUBase = SrcVBase = SrcYBase;
18647104f784Smrg	    SrcUVPitch = SrcYPitch;
18657104f784Smrg	    break;
18667104f784Smrg
18677104f784Smrg	default:
18687104f784Smrg	    LEAVE();
18697104f784Smrg    }
18707104f784Smrg
18717104f784Smrg    WRITE_DPR(pSmi, 0xE4, ((SrcYPitch >> 4) << 16) | (SrcUVPitch >> 4));
18727104f784Smrg    WRITE_DPR(pSmi, 0xC8, SrcYBase);
18737104f784Smrg    WRITE_DPR(pSmi, 0xD8, SrcUBase);
18747104f784Smrg    WRITE_DPR(pSmi, 0xDC, SrcVBase);
18757104f784Smrg    WRITE_DPR(pSmi, 0xF4, (((ScaleXn << 13) | ScaleXd) << 16) |
18767104f784Smrg	      (ScaleYn << 13 | ScaleYd));
18777104f784Smrg
18787104f784Smrg    for (i = 0; i < nbox; i++, pbox++) {
18797104f784Smrg	rect_x = pbox->x1;
18807104f784Smrg	rect_y = pbox->y1;
18817104f784Smrg	rect_w = pbox->x2 - pbox->x1;
18827104f784Smrg	rect_h = pbox->y2 - pbox->y1;
18837104f784Smrg
18847104f784Smrg	SrcLn = (rect_x - dstBox->x1) * Hscale;
18857104f784Smrg	SrcLd = ((rect_x - dstBox->x1) << 13) * Hscale - (SrcLn << 13);
18867104f784Smrg	SrcRn = (rect_x + rect_w - dstBox->x1) * Hscale;
18877104f784Smrg
18887104f784Smrg	SrcTn = (rect_y - dstBox->y1) * Vscale;
18897104f784Smrg	SrcTd = ((rect_y - dstBox->y1) << 13) * Vscale - (SrcTn << 13);
18907104f784Smrg	SrcBn = (rect_y + rect_h - dstBox->y1) * Vscale;
18917104f784Smrg
18927104f784Smrg	SrcDimX = SrcRn - SrcLn + 2;
18937104f784Smrg	SrcDimY = SrcBn - SrcTn + 2;
18947104f784Smrg
18957104f784Smrg	WRITE_DPR(pSmi, 0xD0, (SrcLn << 16) | SrcLd);
18967104f784Smrg	WRITE_DPR(pSmi, 0xD4, (SrcTn << 16) | SrcTd);
18977104f784Smrg	WRITE_DPR(pSmi, 0xE0, (SrcDimX << 16) | SrcDimY);
18987104f784Smrg	WRITE_DPR(pSmi, 0xE8, (rect_x << 16) | rect_y);
18997104f784Smrg	WRITE_DPR(pSmi, 0xEC, (rect_w << 16) | rect_h);
19007104f784Smrg	WRITE_DPR(pSmi, 0xF0, ((DestPitch >> 4) << 16) | rect_h);
19017104f784Smrg
19027104f784Smrg	while (READ_DPR(pSmi, 0xfc) & (1 << 31))
19037104f784Smrg	    ;
19047104f784Smrg	WRITE_DPR(pSmi, 0xfc, csc);
19057104f784Smrg	/* CSC stop */
19067104f784Smrg	while (READ_DPR(pSmi, 0xfc) & (1 << 31))
19077104f784Smrg	    ;
19087104f784Smrg    }
19097104f784Smrg
19107104f784Smrg    LEAVE();
19117104f784Smrg}
19127104f784Smrg
19137104f784Smrgstatic void
19147104f784SmrgSMI_DisplayVideo0501(ScrnInfoPtr pScrn,
19157104f784Smrg		     int id,
19167104f784Smrg		     int offset,
19177104f784Smrg		     short width,
19187104f784Smrg		     short height,
19197104f784Smrg		     int pitch,
19207104f784Smrg		     int x1,
19217104f784Smrg		     int y1,
19227104f784Smrg		     int x2,
19237104f784Smrg		     int y2,
19247104f784Smrg		     BoxPtr dstBox,
19257104f784Smrg		     short vid_w, short vid_h, short drw_w, short drw_h)
19267104f784Smrg{
19277104f784Smrg    SMIPtr	pSmi = SMIPTR (pScrn);
19287104f784Smrg    CARD32	dcr40;
19297104f784Smrg    int		hstretch, vstretch;
19307104f784Smrg
19317104f784Smrg    ENTER();
19327104f784Smrg
19337104f784Smrg    dcr40 = READ_DCR(pSmi, 0x0040) & ~0x00003FFF;
19347104f784Smrg
19357104f784Smrg    switch (id) {
19367104f784Smrg	case FOURCC_YV12:
19377104f784Smrg	case FOURCC_I420:
19387104f784Smrg	case FOURCC_YUY2:
19397104f784Smrg	    dcr40 |= 0x3;
19407104f784Smrg	    break;
19417104f784Smrg
19427104f784Smrg	case FOURCC_RV16:
19437104f784Smrg	    dcr40 |= 0x1;
19447104f784Smrg	    break;
19457104f784Smrg
19467104f784Smrg	case FOURCC_RV32:
19477104f784Smrg	    dcr40 |= 0x2;
19487104f784Smrg	    break;
19497104f784Smrg    }
19507104f784Smrg
19517104f784Smrg    if (drw_w > vid_w) {	/*  Horizontal Stretch */
19527104f784Smrg	hstretch = 4096 * vid_w / drw_w;
19537104f784Smrg	dcr40 |= 1 << 8;
19547104f784Smrg    }
19557104f784Smrg    else {			/*  Horizontal Shrink */
19567104f784Smrg	if (drw_w < (vid_w >> 1))
19577104f784Smrg	    drw_w = vid_w >> 1;
19587104f784Smrg	hstretch = (4096 * drw_w / vid_w) | 0x8000;
19597104f784Smrg    }
19607104f784Smrg
19617104f784Smrg    if (drw_h > vid_h) {	/* Vertical Stretch */
19627104f784Smrg	vstretch = 4096 * vid_h / drw_h;
19637104f784Smrg	dcr40 |= 1 << 9;
19647104f784Smrg    }
19657104f784Smrg    else {			/* Vertical Shrink */
19667104f784Smrg	if (drw_h < (vid_h >> 1))
19677104f784Smrg	    drw_h = vid_h >> 1;
19687104f784Smrg	vstretch = (4096 * drw_h / vid_h) | 0x8000;
19697104f784Smrg    }
19707104f784Smrg
19717104f784Smrg    /* Set Color Key Enable bit */
19727104f784Smrg
19737104f784Smrg    WRITE_DCR(pSmi, 0x0000, READ_DCR(pSmi, 0x0000) | (1 << 9));
19747104f784Smrg    WRITE_DCR(pSmi, 0x0050, dstBox->x1 | (dstBox->y1 << 16));
19757104f784Smrg    WRITE_DCR(pSmi, 0x0054, dstBox->x2 | (dstBox->y2 << 16));
19767104f784Smrg    WRITE_DCR(pSmi, 0x0044, offset);
19777104f784Smrg
19787104f784Smrg    WRITE_DCR(pSmi, 0x0048, pitch | (pitch << 16));
19797104f784Smrg    WRITE_DCR(pSmi, 0x004C, offset + (pitch * height));
19807104f784Smrg    WRITE_DCR(pSmi, 0x0058, (vstretch << 16) | hstretch);
19817104f784Smrg    WRITE_DCR(pSmi, 0x005C, 0x00000000);
19827104f784Smrg    WRITE_DCR(pSmi, 0x0060, 0x00EDEDED);
19837104f784Smrg
19847104f784Smrg    WRITE_DCR(pSmi, 0x0040, dcr40 | (1 << 2));
19857104f784Smrg
19867104f784Smrg    LEAVE();
198709885543Smrg}
198809885543Smrg
198909885543Smrgstatic void
199009885543SmrgSMI_DisplayVideo0730(
199109885543Smrg	ScrnInfoPtr	pScrn,
199209885543Smrg	int		id,
199309885543Smrg	int		offset,
199409885543Smrg	short		width,
199509885543Smrg	short		height,
199609885543Smrg	int		pitch,
199709885543Smrg	int		x1,
199809885543Smrg	int		y1,
199909885543Smrg	int		x2,
200009885543Smrg	int		y2,
200109885543Smrg	BoxPtr		dstBox,
200209885543Smrg	short		vid_w,
200309885543Smrg	short		vid_h,
200409885543Smrg	short		drw_w,
200509885543Smrg	short		drw_h
200609885543Smrg)
200709885543Smrg{
200809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
200909885543Smrg    CARD32 fpr00;
201009885543Smrg    int hstretch, vstretch;
201109885543Smrg
20127104f784Smrg    ENTER();
201309885543Smrg
201409885543Smrg    fpr00 = READ_FPR(pSmi, 0x00) & ~(FPR00_MASKBITS);
201509885543Smrg
201609885543Smrg    switch (id) {
201709885543Smrg    case FOURCC_YV12:
201809885543Smrg    case FOURCC_I420:
201909885543Smrg    case FOURCC_YUY2:
202009885543Smrg	fpr00 |= FPR00_FMT_YUV422;
202109885543Smrg	break;
202209885543Smrg    case FOURCC_RV15:
202309885543Smrg	fpr00 |= FPR00_FMT_15P;
202409885543Smrg	break;
202509885543Smrg    case FOURCC_RV16:
202609885543Smrg	fpr00 |= FPR00_FMT_16P;
202709885543Smrg	break;
202809885543Smrg    case FOURCC_RV24:
202909885543Smrg	fpr00 |= FPR00_FMT_24P;
203009885543Smrg	break;
203109885543Smrg    case FOURCC_RV32:
203209885543Smrg	fpr00 |= FPR00_FMT_32P;
203309885543Smrg	break;
203409885543Smrg    }
203509885543Smrg
203609885543Smrg    /* the formulas for calculating the stretch values do not match the
203709885543Smrg       documentation, but they're the same as the ddraw driver and they work */
203809885543Smrg    if (drw_w > vid_w) {
203909885543Smrg	hstretch = (8192 * vid_w / drw_w);
204009885543Smrg    } else {
204109885543Smrg	hstretch = 0;
204209885543Smrg    }
204309885543Smrg
204409885543Smrg    if (drw_h > vid_h) {
204509885543Smrg	vstretch = (8192 * vid_h / drw_h);
204609885543Smrg    } else {
204709885543Smrg	vstretch = 0;
204809885543Smrg    }
204909885543Smrg
205009885543Smrg    WRITE_FPR(pSmi, FPR00, fpr00 | FPR00_VWIENABLE | FPR00_VWIKEYENABLE);
205109885543Smrg    WRITE_FPR(pSmi, FPR14, (dstBox->x1) | (dstBox->y1 << 16));
205209885543Smrg    WRITE_FPR(pSmi, FPR18, (dstBox->x2) | (dstBox->y2 << 16));
205309885543Smrg    WRITE_FPR(pSmi, FPR1C, offset >> 3);
205409885543Smrg    WRITE_FPR(pSmi, FPR20, (pitch >> 3) | ((pitch >> 3) << 16));
205509885543Smrg    WRITE_FPR(pSmi, FPR24, (hstretch & 0xFF00) | ((vstretch & 0xFF00)>>8));
205609885543Smrg    WRITE_FPR(pSmi, FPR68, ((hstretch & 0x00FF)<<8) | (vstretch & 0x00FF));
205709885543Smrg
20587104f784Smrg    LEAVE();
205909885543Smrg}
206009885543Smrg
206109885543Smrgstatic void
206209885543SmrgSMI_BlockHandler(
206309885543Smrg	int	i,
206409885543Smrg	pointer	blockData,
206509885543Smrg	pointer	pTimeout,
206609885543Smrg	pointer	pReadMask
206709885543Smrg)
206809885543Smrg{
206909885543Smrg    ScreenPtr	pScreen = screenInfo.screens[i];
207009885543Smrg    ScrnInfoPtr	pScrn	= xf86Screens[i];
207109885543Smrg    SMIPtr	pSmi    = SMIPTR(pScrn);
207209885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
207309885543Smrg
207409885543Smrg    pScreen->BlockHandler = pSmi->BlockHandler;
207509885543Smrg    (*pScreen->BlockHandler)(i, blockData, pTimeout, pReadMask);
207609885543Smrg    pScreen->BlockHandler = SMI_BlockHandler;
207709885543Smrg
207809885543Smrg    if (pPort->videoStatus & TIMER_MASK) {
207909885543Smrg	UpdateCurrentTime();
208009885543Smrg        if (pPort->videoStatus & OFF_TIMER) {
208109885543Smrg            if (pPort->offTime < currentTime.milliseconds) {
208209885543Smrg		if (pSmi->Chipset == SMI_COUGAR3DR) {
208309885543Smrg		    WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE));
208409885543Smrg		}
20857104f784Smrg		else if (IS_MSOC(pSmi))
20867104f784Smrg		    WRITE_DCR(pSmi, 0x0040, READ_DCR(pSmi, 0x0040) & ~0x00000004);
20877104f784Smrg		else
20887104f784Smrg		    WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008);
208909885543Smrg                pPort->videoStatus = FREE_TIMER;
209009885543Smrg                pPort->freeTime = currentTime.milliseconds + FREE_DELAY;
209109885543Smrg	    }
209209885543Smrg	} else {
209309885543Smrg            if (pPort->freeTime < currentTime.milliseconds) {
209409885543Smrg		SMI_FreeMemory(pScrn, pPort->video_memory);
209509885543Smrg                pPort->video_memory = NULL;
209609885543Smrg	    }
209709885543Smrg            pPort->videoStatus = 0;
209809885543Smrg	}
209909885543Smrg    }
210009885543Smrg}
210109885543Smrg
210209885543Smrg#if 0
210309885543Smrgstatic int
210409885543SmrgSMI_SendI2C(
210509885543Smrg	ScrnInfoPtr		pScrn,
210609885543Smrg	CARD8			device,
210709885543Smrg	char			*devName,
210809885543Smrg	SMI_I2CDataPtr	i2cData
210909885543Smrg)
211009885543Smrg{
21117104f784Smrg    SMIPtr	pSmi = SMIPTR(pScrn);
21127104f784Smrg    I2CDevPtr	dev;
21137104f784Smrg    int		status = Success;
211409885543Smrg
21157104f784Smrg    ENTER();
211609885543Smrg
21177104f784Smrg    if (pSmi->I2C == NULL)
21187104f784Smrg	LEAVE(BadAlloc);
211909885543Smrg
21207104f784Smrg    dev = xf86CreateI2CDevRec();
21217104f784Smrg    if (dev == NULL)
21227104f784Smrg	LEAVE(BadAlloc);
212309885543Smrg
21247104f784Smrg    dev->DevName = devName;
21257104f784Smrg    dev->SlaveAddr = device;
21267104f784Smrg    dev->pI2CBus = pSmi->I2C;
21277104f784Smrg
21287104f784Smrg    if (!xf86I2CDevInit(dev))
21297104f784Smrg	status = BadAlloc;
21307104f784Smrg    else {
21317104f784Smrg	while (i2cData->address != 0xFF || i2cData->data != 0xFF) {	/* PDR#676 */
21327104f784Smrg	    if (!xf86I2CWriteByte(dev, i2cData->address, i2cData->data)) {
213309885543Smrg		status = BadAlloc;
21347104f784Smrg		break;
21357104f784Smrg	    }
21367104f784Smrg	    i2cData++;
213709885543Smrg	}
21387104f784Smrg    }
213909885543Smrg
21407104f784Smrg    xf86DestroyI2CDevRec(dev, TRUE);
21417104f784Smrg
21427104f784Smrg    LEAVE(status);
214309885543Smrg}
214409885543Smrg#endif
214509885543Smrg
214609885543Smrg/******************************************************************************\
214709885543Smrg**									      **
214809885543Smrg**	 O F F S C R E E N   M E M O R Y   M A N A G E R		      **
214909885543Smrg**									      **
215009885543Smrg\******************************************************************************/
215109885543Smrg
215209885543Smrgstatic void
215309885543SmrgSMI_InitOffscreenImages(
215409885543Smrg	ScreenPtr	pScreen
215509885543Smrg)
215609885543Smrg{
215709885543Smrg    XF86OffscreenImagePtr offscreenImages;
215809885543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
215909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
216009885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
216109885543Smrg
21627104f784Smrg    ENTER();
216309885543Smrg
216409885543Smrg    offscreenImages = xalloc(sizeof(XF86OffscreenImageRec));
216509885543Smrg    if (offscreenImages == NULL) {
21667104f784Smrg	LEAVE();
216709885543Smrg    }
216809885543Smrg
216909885543Smrg    offscreenImages->image = SMI_VideoImages;
21707104f784Smrg    offscreenImages->flags = VIDEO_OVERLAID_IMAGES;
21717104f784Smrg    if (IS_MSOC(pSmi))
21727104f784Smrg	offscreenImages->flags |= VIDEO_CLIP_TO_VIEWPORT;
217309885543Smrg    offscreenImages->alloc_surface = SMI_AllocSurface;
217409885543Smrg    offscreenImages->free_surface = SMI_FreeSurface;
217509885543Smrg    offscreenImages->display = SMI_DisplaySurface;
217609885543Smrg    offscreenImages->stop = SMI_StopSurface;
217709885543Smrg    offscreenImages->getAttribute = SMI_GetSurfaceAttribute;
217809885543Smrg    offscreenImages->setAttribute = SMI_SetSurfaceAttribute;
217909885543Smrg    offscreenImages->max_width = pSmi->lcdWidth;
218009885543Smrg    offscreenImages->max_height = pSmi->lcdHeight;
218109885543Smrg    if (!pPort->I2CDev.SlaveAddr) {
218209885543Smrg	offscreenImages->num_attributes = nElems(SMI_VideoAttributes);
218309885543Smrg	offscreenImages->attributes = SMI_VideoAttributes;
218409885543Smrg    } else {
218509885543Smrg	offscreenImages->num_attributes = nElems(SMI_VideoAttributesSAA711x);
218609885543Smrg	offscreenImages->attributes = SMI_VideoAttributesSAA711x;
218709885543Smrg    }
218809885543Smrg    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
218909885543Smrg
21907104f784Smrg    LEAVE();
219109885543Smrg}
219209885543Smrg
219309885543Smrgstatic void
219409885543SmrgSMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area)
219509885543Smrg{
219609885543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
219709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
219809885543Smrg    SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr;
219909885543Smrg
22007104f784Smrg    ENTER();
220109885543Smrg
220209885543Smrg    if (pPort->video_memory == area)
220309885543Smrg	pPort->video_memory = NULL;
220409885543Smrg
22057104f784Smrg    LEAVE();
220609885543Smrg}
220709885543Smrg
22087104f784SmrgCARD32
22097104f784SmrgSMI_AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size)
221009885543Smrg{
22117104f784Smrg    ScreenPtr	pScreen = screenInfo.screens[pScrn->scrnIndex];
22127104f784Smrg    SMIPtr	pSmi = SMIPTR(pScrn);
22137104f784Smrg    int		offset = 0;
221409885543Smrg
22157104f784Smrg    ENTER();
221609885543Smrg
221709885543Smrg    if (pSmi->useEXA) {
221809885543Smrg	ExaOffscreenArea *area = *mem_struct;
221909885543Smrg
222009885543Smrg	if (area != NULL) {
222109885543Smrg	    if (area->size >= size)
22227104f784Smrg		LEAVE(area->offset);
222309885543Smrg
222409885543Smrg	    exaOffscreenFree(pScrn->pScreen, area);
222509885543Smrg	}
222609885543Smrg
22277104f784Smrg	area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE,
22287104f784Smrg				 SMI_VideoSave, NULL);
222909885543Smrg
223009885543Smrg	*mem_struct = area;
22317104f784Smrg	if (area != NULL)
22327104f784Smrg	    offset = area->offset;
22337104f784Smrg    }
22347104f784Smrg    else {
22357104f784Smrg	FBLinearPtr	linear = *mem_struct;
223609885543Smrg
223709885543Smrg	/*  XAA allocates in units of pixels at the screen bpp,
223809885543Smrg	 *  so adjust size appropriately.
223909885543Smrg	 */
224009885543Smrg	size = (size + pSmi->Bpp - 1) / pSmi->Bpp;
224109885543Smrg
224209885543Smrg	if (linear) {
224309885543Smrg	    if (linear->size >= size)
22447104f784Smrg		LEAVE(linear->offset * pSmi->Bpp);
224509885543Smrg
224609885543Smrg	    if (xf86ResizeOffscreenLinear(linear, size))
22477104f784Smrg		LEAVE(linear->offset * pSmi->Bpp);
224809885543Smrg
22497104f784Smrg	    xf86FreeOffscreenLinear(linear);
22507104f784Smrg	}
22517104f784Smrg	else {
22527104f784Smrg	    int max_size;
225309885543Smrg
22547104f784Smrg	    xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16,
22557104f784Smrg					    PRIORITY_EXTREME);
22567104f784Smrg	    if (max_size < size)
22577104f784Smrg		LEAVE(0);
225809885543Smrg
22597104f784Smrg	    xf86PurgeUnlockedOffscreenAreas(pScreen);
226009885543Smrg	}
226109885543Smrg
22627104f784Smrg	linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
22637104f784Smrg					     NULL, NULL, NULL);
22647104f784Smrg	if ((*mem_struct = linear) != NULL)
22657104f784Smrg	    offset = linear->offset * pSmi->Bpp;
22667104f784Smrg
22677104f784Smrg	DEBUG("offset = %p\n", offset);
226809885543Smrg    }
226909885543Smrg
22707104f784Smrg    LEAVE(offset);
227109885543Smrg}
227209885543Smrg
22737104f784Smrgvoid
227409885543SmrgSMI_FreeMemory(
227509885543Smrg	ScrnInfoPtr pScrn,
227609885543Smrg	void *mem_struct
227709885543Smrg)
227809885543Smrg{
227909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
228009885543Smrg
22817104f784Smrg    ENTER();
228209885543Smrg
228309885543Smrg    if (pSmi->useEXA) {
228409885543Smrg	ExaOffscreenArea *area = mem_struct;
228509885543Smrg
228609885543Smrg	if (area != NULL)
228709885543Smrg	    exaOffscreenFree(pScrn->pScreen, area);
228809885543Smrg    } else {
228909885543Smrg	FBLinearPtr linear = mem_struct;
229009885543Smrg
229109885543Smrg	if (linear != NULL)
229209885543Smrg	    xf86FreeOffscreenLinear(linear);
229309885543Smrg    }
229409885543Smrg
22957104f784Smrg    LEAVE();
22967104f784Smrg}
22977104f784Smrg
22987104f784Smrgstatic void
22997104f784SmrgCopyYV12ToVideoMem(unsigned char *src1, unsigned char *src2,
23007104f784Smrg		   unsigned char *src3, unsigned char *dst,
23017104f784Smrg		   int src1Pitch, int src23Pitch, int dstPitch,
23027104f784Smrg		   int height, int width)
23037104f784Smrg{
23047104f784Smrg    int		j = height;
23057104f784Smrg
23067104f784Smrg    ENTER();
23077104f784Smrg
23087104f784Smrg    /* copy 1 data */
23097104f784Smrg    while (j -- > 0) {
23107104f784Smrg	memcpy(dst, src1, width);
23117104f784Smrg	src1 += src1Pitch;
23127104f784Smrg	dst += dstPitch;
23137104f784Smrg    }
23147104f784Smrg    /* copy 2 data */
23157104f784Smrg    j = height / 2;
23167104f784Smrg    while (j -- > 0) {
23177104f784Smrg	memcpy(dst, src2, width / 2);
23187104f784Smrg	src2 += src23Pitch;
23197104f784Smrg	dst += dstPitch / 2;
23207104f784Smrg    }
23217104f784Smrg    /* copy 3 data */
23227104f784Smrg    j = height / 2;
23237104f784Smrg    while (j -- > 0) {
23247104f784Smrg	memcpy(dst, src3, width / 2);
23257104f784Smrg	src3 += src23Pitch;
23267104f784Smrg	dst += dstPitch / 2;
23277104f784Smrg    }
23287104f784Smrg
23297104f784Smrg    LEAVE();
233009885543Smrg}
233109885543Smrg
233209885543Smrgstatic int
233309885543SmrgSMI_AllocSurface(
233409885543Smrg	ScrnInfoPtr	pScrn,
233509885543Smrg	int		id,
233609885543Smrg	unsigned short	width,
233709885543Smrg	unsigned short	height,
233809885543Smrg	XF86SurfacePtr	surface
233909885543Smrg)
234009885543Smrg{
234109885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
234209885543Smrg    int pitch, bpp, offset, size;
234309885543Smrg    void *surface_memory = NULL;
234409885543Smrg    SMI_OffscreenPtr ptrOffscreen;
234509885543Smrg
23467104f784Smrg    ENTER();
234709885543Smrg
23487104f784Smrg    if (width > pSmi->lcdWidth || height > pSmi->lcdHeight)
23497104f784Smrg	LEAVE(BadAlloc);
235009885543Smrg
235109885543Smrg    switch (id) {
235209885543Smrg    case FOURCC_YV12:
235309885543Smrg    case FOURCC_I420:
235409885543Smrg    case FOURCC_YUY2:
235509885543Smrg    case FOURCC_RV15:
235609885543Smrg    case FOURCC_RV16:
235709885543Smrg	bpp = 2;
235809885543Smrg	break;
235909885543Smrg    case FOURCC_RV24:
236009885543Smrg	bpp = 3;
236109885543Smrg	break;
236209885543Smrg    case FOURCC_RV32:
236309885543Smrg	bpp = 4;
236409885543Smrg	break;
236509885543Smrg    default:
23667104f784Smrg	LEAVE(BadAlloc);
236709885543Smrg    }
236809885543Smrg
236909885543Smrg    width = (width + 1) & ~1;
237009885543Smrg    pitch = (width * bpp + 15) & ~15;
237109885543Smrg    size  = pitch * height;
237209885543Smrg
237309885543Smrg    offset = SMI_AllocateMemory(pScrn, &surface_memory, size);
23747104f784Smrg    if (offset == 0)
23757104f784Smrg	LEAVE(BadAlloc);
237609885543Smrg
237709885543Smrg    surface->pitches = xalloc(sizeof(int));
237809885543Smrg    if (surface->pitches == NULL) {
237909885543Smrg	SMI_FreeMemory(pScrn, surface_memory);
23807104f784Smrg	LEAVE(BadAlloc);
238109885543Smrg    }
238209885543Smrg    surface->offsets = xalloc(sizeof(int));
238309885543Smrg    if (surface->offsets == NULL) {
238409885543Smrg	xfree(surface->pitches);
238509885543Smrg	SMI_FreeMemory(pScrn, surface_memory);
23867104f784Smrg	LEAVE(BadAlloc);
238709885543Smrg    }
238809885543Smrg
238909885543Smrg    ptrOffscreen = xalloc(sizeof(SMI_OffscreenRec));
239009885543Smrg    if (ptrOffscreen == NULL) {
239109885543Smrg	xfree(surface->offsets);
239209885543Smrg	xfree(surface->pitches);
239309885543Smrg	SMI_FreeMemory(pScrn, surface_memory);
23947104f784Smrg	LEAVE(BadAlloc);
239509885543Smrg    }
239609885543Smrg
239709885543Smrg    surface->pScrn = pScrn;
239809885543Smrg    surface->id = id;
239909885543Smrg    surface->width = width;
240009885543Smrg    surface->height = height;
240109885543Smrg    surface->pitches[0] = pitch;
240209885543Smrg    surface->offsets[0] = offset;
240309885543Smrg    surface->devPrivate.ptr = (pointer) ptrOffscreen;
240409885543Smrg
240509885543Smrg    ptrOffscreen->surface_memory = surface_memory;
240609885543Smrg    ptrOffscreen->isOn = FALSE;
240709885543Smrg
24087104f784Smrg    LEAVE(Success);
240909885543Smrg}
241009885543Smrg
241109885543Smrgstatic int
241209885543SmrgSMI_FreeSurface(
241309885543Smrg	XF86SurfacePtr	surface
241409885543Smrg)
241509885543Smrg{
241609885543Smrg    ScrnInfoPtr pScrn = surface->pScrn;
241709885543Smrg    SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr;
241809885543Smrg
24197104f784Smrg    ENTER();
242009885543Smrg
242109885543Smrg    if (ptrOffscreen->isOn) {
242209885543Smrg	SMI_StopSurface(surface);
242309885543Smrg    }
242409885543Smrg
242509885543Smrg    SMI_FreeMemory(pScrn, ptrOffscreen->surface_memory);
242609885543Smrg    xfree(surface->pitches);
242709885543Smrg    xfree(surface->offsets);
242809885543Smrg    xfree(surface->devPrivate.ptr);
242909885543Smrg
24307104f784Smrg    LEAVE(Success);
243109885543Smrg}
243209885543Smrg
243309885543Smrgstatic int
243409885543SmrgSMI_DisplaySurface(
243509885543Smrg	XF86SurfacePtr	surface,
243609885543Smrg	short		vid_x,
243709885543Smrg	short		vid_y,
243809885543Smrg	short		drw_x,
243909885543Smrg	short		drw_y,
244009885543Smrg	short		vid_w,
244109885543Smrg	short		vid_h,
244209885543Smrg	short		drw_w,
244309885543Smrg	short		drw_h,
244409885543Smrg	RegionPtr	clipBoxes
244509885543Smrg)
244609885543Smrg{
244709885543Smrg    SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr;
244809885543Smrg    SMIPtr pSmi = SMIPTR(surface->pScrn);
244909885543Smrg    SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr;
245009885543Smrg    INT32 x1, y1, x2, y2;
245109885543Smrg    BoxRec dstBox;
24527104f784Smrg    xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(surface->pScrn);
24537104f784Smrg    xf86CrtcPtr crtc;
245409885543Smrg
24557104f784Smrg    ENTER();
245609885543Smrg
245709885543Smrg    x1 = vid_x;
245809885543Smrg    x2 = vid_x + vid_w;
245909885543Smrg    y1 = vid_y;
246009885543Smrg    y2 = vid_y + vid_h;
246109885543Smrg
246209885543Smrg    dstBox.x1 = drw_x;
246309885543Smrg    dstBox.x2 = drw_x + drw_w;
246409885543Smrg    dstBox.y1 = drw_y;
246509885543Smrg    dstBox.y2 = drw_y + drw_h;
246609885543Smrg
24677104f784Smrg    if(!xf86_crtc_clip_video_helper(surface->pScrn, &crtc, crtcConf->crtc[0], &dstBox,
24687104f784Smrg				    &x1, &x2, &y1, &y2, clipBoxes, surface->width, surface->height))
24697104f784Smrg	LEAVE(Success);
247009885543Smrg
24717104f784Smrg    /* Transform dstBox to the CRTC coordinates */
24727104f784Smrg    dstBox.x1 -= crtc->x;
24737104f784Smrg    dstBox.y1 -= crtc->y;
24747104f784Smrg    dstBox.x2 -= crtc->x;
24757104f784Smrg    dstBox.y2 -= crtc->y;
247609885543Smrg
247709885543Smrg    xf86XVFillKeyHelper(surface->pScrn->pScreen,
247809885543Smrg			pPort->Attribute[XV_COLORKEY], clipBoxes);
24797104f784Smrg    SMI_ResetVideo(surface->pScrn);
248009885543Smrg
24817104f784Smrg    if (pSmi->Chipset == SMI_COUGAR3DR)
248209885543Smrg	SMI_DisplayVideo0730(surface->pScrn, surface->id, surface->offsets[0],
248309885543Smrg			     surface->width, surface->height, surface->pitches[0], x1, y1, x2,
248409885543Smrg			     y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
24857104f784Smrg    else if (IS_MSOC(pSmi))
24867104f784Smrg	SMI_DisplayVideo0501(surface->pScrn, surface->id,
24877104f784Smrg			     surface->offsets[0], surface->width,
24887104f784Smrg			     surface->height, surface->pitches[0], x1, y1,
24897104f784Smrg			     x2, y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
24907104f784Smrg    else{
24917104f784Smrg	if(crtc == crtcConf->crtc[0])
24927104f784Smrg	    SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0],
24937104f784Smrg			     surface->width, surface->height, surface->pitches[0], x1, y1, x2,
24947104f784Smrg			     y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
249509885543Smrg    }
249609885543Smrg
249709885543Smrg    ptrOffscreen->isOn = TRUE;
249809885543Smrg    if (pPort->videoStatus & CLIENT_VIDEO_ON) {
249909885543Smrg        REGION_EMPTY(surface->pScrn->pScreen, &pPort->clip);
250009885543Smrg	UpdateCurrentTime();
250109885543Smrg        pPort->videoStatus = FREE_TIMER;
250209885543Smrg        pPort->freeTime = currentTime.milliseconds + FREE_DELAY;
250309885543Smrg    }
250409885543Smrg
25057104f784Smrg    LEAVE(Success);
250609885543Smrg}
250709885543Smrg
250809885543Smrgstatic int
250909885543SmrgSMI_StopSurface(
251009885543Smrg	XF86SurfacePtr	surface
251109885543Smrg)
251209885543Smrg{
251309885543Smrg    SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr;
251409885543Smrg
25157104f784Smrg    ENTER();
251609885543Smrg
251709885543Smrg    if (ptrOffscreen->isOn) {
251809885543Smrg	SMIPtr pSmi = SMIPTR(surface->pScrn);
251909885543Smrg	if (pSmi->Chipset == SMI_COUGAR3DR) {
252009885543Smrg	    WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE));
252109885543Smrg	} else {
252209885543Smrg	    WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008);
252309885543Smrg	}
252409885543Smrg
252509885543Smrg	ptrOffscreen->isOn = FALSE;
252609885543Smrg    }
252709885543Smrg
25287104f784Smrg    LEAVE(Success);
252909885543Smrg}
253009885543Smrg
253109885543Smrgstatic int
253209885543SmrgSMI_GetSurfaceAttribute(
253309885543Smrg	ScrnInfoPtr	pScrn,
253409885543Smrg	Atom		attr,
253509885543Smrg	INT32		*value
253609885543Smrg)
253709885543Smrg{
253809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
253909885543Smrg
254009885543Smrg    return SMI_GetPortAttribute(pScrn, attr, value,
254109885543Smrg			(pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr);
254209885543Smrg}
254309885543Smrg
254409885543Smrgstatic int
254509885543SmrgSMI_SetSurfaceAttribute(
254609885543Smrg	ScrnInfoPtr	pScrn,
254709885543Smrg	Atom		attr,
254809885543Smrg	INT32		value
254909885543Smrg)
255009885543Smrg{
255109885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
255209885543Smrg
255309885543Smrg    return SMI_SetPortAttribute(pScrn, attr, value,
255409885543Smrg			(pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr);
255509885543Smrg}
255609885543Smrg
255709885543Smrgstatic void
255809885543SmrgSetKeyReg(SMIPtr pSmi, int reg, int value)
255909885543Smrg{
25607104f784Smrg    if (pSmi->Chipset == SMI_COUGAR3DR)
256109885543Smrg	WRITE_FPR(pSmi, reg, value);
25627104f784Smrg    else if (IS_MSOC(pSmi)) {
25637104f784Smrg	/* We don't change the color mask, and we don't do brightness.  IF
25647104f784Smrg	 * they write to the colorkey register, we'll write the value to the
25657104f784Smrg	 * 501 colorkey register */
25667104f784Smrg	if (FPR04 == reg)		   /* Only act on colorkey value writes */
25677104f784Smrg	    WRITE_DCR(pSmi, 0x0008, value);/* ColorKey register is DCR08 */
256809885543Smrg    }
25697104f784Smrg    else
25707104f784Smrg	WRITE_VPR(pSmi, reg, value);
257109885543Smrg}
257209885543Smrg
257309885543Smrg#else /* SMI_USE_VIDEO */
257409885543Smrgvoid SMI_InitVideo(ScreenPtr pScreen) {}
257509885543Smrg#endif
2576