smi_video.c revision b12e5c03
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);
126b12e5c03Smrgstatic void SMI_BlockHandler(BLOCKHANDLER_ARGS_DECL);
12709885543Smrg/*static int SMI_SendI2C(ScrnInfoPtr pScrn, CARD8 device, char *devName,
12809885543Smrg        SMI_I2CDataPtr i2cData);*/
12909885543Smrg
13009885543Smrgstatic void SMI_InitOffscreenImages(ScreenPtr pScreen);
13109885543Smrgstatic void SMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area);
13209885543Smrg
1337104f784Smrgstatic void CopyYV12ToVideoMem(unsigned char *src1, unsigned char *src2,
1347104f784Smrg			       unsigned char *src3, unsigned char *dst,
1357104f784Smrg			       int src1Pitch, int src23Pitch, int dstPitch,
1367104f784Smrg			       int height, int width);
13709885543Smrgstatic int SMI_AllocSurface(ScrnInfoPtr pScrn,
13809885543Smrg		int id, unsigned short width, unsigned short height,
13909885543Smrg		XF86SurfacePtr surface);
14009885543Smrgstatic int SMI_FreeSurface(XF86SurfacePtr surface);
14109885543Smrgstatic int SMI_DisplaySurface(XF86SurfacePtr surface,
14209885543Smrg		short vid_x, short vid_y, short drw_x, short drw_y,
14309885543Smrg		short vid_w, short vid_h, short drw_w, short drw_h,
14409885543Smrg		RegionPtr clipBoxes);
14509885543Smrgstatic int SMI_StopSurface(XF86SurfacePtr surface);
14609885543Smrgstatic int SMI_GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 *value);
14709885543Smrgstatic int SMI_SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 value);
14809885543Smrg
14909885543Smrgstatic int SetAttr(ScrnInfoPtr pScrn, int i, int value);
15009885543Smrgstatic int SetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value);
15109885543Smrgstatic int SetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value);
15209885543Smrgstatic void SetKeyReg(SMIPtr pSmi, int reg, int value);
15309885543Smrg
15409885543Smrg/**
15509885543Smrg * Atoms
15609885543Smrg */
15709885543Smrg
15809885543Smrgstatic Atom xvColorKey;
15909885543Smrgstatic Atom xvEncoding;
16009885543Smrgstatic Atom xvBrightness,xvCapBrightness, xvContrast, xvSaturation, xvHue;
16109885543Smrgstatic Atom xvInterlaced;
16209885543Smrg
16309885543Smrg
16409885543Smrg/******************************************************************************\
16509885543Smrg**																			  **
16609885543Smrg**                           C A P A B I L I T I E S                          **
16709885543Smrg**																			  **
16809885543Smrg\******************************************************************************/
16909885543Smrg
17009885543Smrg
17109885543Smrg/**************************************************************************/
17209885543Smrg/* input channels */
17309885543Smrg
17409885543Smrg#define N_COMPOSITE_CHANNELS 4
17509885543Smrg#define N_SVIDEO_CHANNELS 2
17609885543Smrg
17709885543Smrg#define N_VIDEO_INPUTS 2
17809885543Smrgtypedef enum _VideoInput { VID_COMPOSITE, VID_SVIDEO } VideoInput;
17909885543Smrg
18009885543Smrg
18109885543Smrg/**************************************************************************/
18209885543Smrg/* video input formats */
18309885543Smrg
18409885543Smrgtypedef struct _VideoInputDataRec {
18509885543Smrg    char* name;
18609885543Smrg} VideoInputDataRec;
18709885543Smrg
18809885543Smrgstatic VideoInputDataRec VideoInputs[] = {
18909885543Smrg    { "composite" },
19009885543Smrg    { "svideo" }
19109885543Smrg};
19209885543Smrg
19309885543Smrg
19409885543Smrg/**************************************************************************/
19509885543Smrg/* video norms */
19609885543Smrg
19709885543Smrg#define N_VIDEO_NORMS 3
19809885543Smrgtypedef enum _VideoNorm { PAL, NTSC, SECAM } VideoNorm;
19909885543Smrg
20009885543Smrgtypedef struct _VideoNormDataRec {
20109885543Smrg    char* name;
20209885543Smrg    unsigned long Wt;
20309885543Smrg    unsigned long Wa;
20409885543Smrg    unsigned long Ht;
20509885543Smrg    unsigned long Ha;
20609885543Smrg    unsigned long HStart;
20709885543Smrg    unsigned long VStart;
20809885543Smrg    XvRationalRec rate;
20909885543Smrg} VideoNormDataRec;
21009885543Smrg
21109885543Smrg
21209885543Smrgstatic VideoNormDataRec VideoNorms[] =
21309885543Smrg{
21409885543Smrg    /* PAL-BDGHI */
21509885543Smrg    {"pal", 864, 704, 625, 576, 16, 16, { 1, 50 }},
21609885543Smrg    /* NTSC */
21709885543Smrg    {"ntsc", 858, 704, 525, 480, 21, 8, { 1001, 60000 }},
21809885543Smrg    /* SECAM (not tested) */
21909885543Smrg    {"secam", 864, 7040, 625, 576, 31, 16, { 1, 50 }},
22009885543Smrg};
22109885543Smrg
22209885543Smrg
22309885543Smrg/**************************************************************************/
22409885543Smrg/* number of (generated) XV_ENCODING vaulues */
22509885543Smrg#define N_ENCODINGS ((N_VIDEO_NORMS) * (N_COMPOSITE_CHANNELS + N_SVIDEO_CHANNELS))
22609885543Smrg
22709885543Smrg
22809885543Smrg/**************************************************************************/
22909885543Smrg
23009885543Smrgstatic XF86VideoFormatRec SMI_VideoFormats[] =
23109885543Smrg{
23209885543Smrg    { 15, TrueColor },	/* depth, class				*/
23309885543Smrg    { 16, TrueColor },	/* depth, class				*/
23409885543Smrg    { 24, TrueColor },	/* depth, class				*/
23509885543Smrg};
23609885543Smrg
23709885543Smrg
23809885543Smrg/**************************************************************************/
23909885543Smrg
24009885543Smrg/**
24109885543Smrg * Attributes
24209885543Smrg */
24309885543Smrg
24409885543Smrg#define XV_ENCODING_NAME        "XV_ENCODING"
24509885543Smrg#define XV_BRIGHTNESS_NAME      "XV_BRIGHTNESS"
24609885543Smrg#define XV_CAPTURE_BRIGHTNESS_NAME      "XV_CAPTURE_BRIGHTNESS"
24709885543Smrg#define XV_CONTRAST_NAME        "XV_CONTRAST"
24809885543Smrg#define XV_SATURATION_NAME      "XV_SATURATION"
24909885543Smrg#define XV_HUE_NAME             "XV_HUE"
25009885543Smrg#define XV_COLORKEY_NAME        "XV_COLORKEY"
25109885543Smrg#define XV_INTERLACED_NAME      "XV_INTERLACED"
25209885543Smrg
25309885543Smrg
25409885543Smrg/* fixed order! */
25509885543Smrgstatic XF86AttributeRec SMI_VideoAttributesSAA711x[N_ATTRS] = {
25609885543Smrg    {XvSettable | XvGettable,        0, N_ENCODINGS-1, XV_ENCODING_NAME},
25709885543Smrg    {XvSettable | XvGettable,        0,           255, XV_BRIGHTNESS_NAME},
25809885543Smrg    {XvSettable | XvGettable,        0,           255, XV_CAPTURE_BRIGHTNESS_NAME},
25909885543Smrg    {XvSettable | XvGettable,        0,           127, XV_CONTRAST_NAME},
26009885543Smrg    {XvSettable | XvGettable,        0,           127, XV_SATURATION_NAME},
26109885543Smrg    {XvSettable | XvGettable,     -128,           127, XV_HUE_NAME},
26209885543Smrg    {XvSettable | XvGettable, 0x000000,      0xFFFFFF, XV_COLORKEY_NAME},
26309885543Smrg    {XvSettable | XvGettable,        0,             1, XV_INTERLACED_NAME},
26409885543Smrg};
26509885543Smrg
26609885543Smrgstatic XF86AttributeRec SMI_VideoAttributes[2] = {
26709885543Smrg    {XvSettable | XvGettable,        0,           255, XV_BRIGHTNESS_NAME},
26809885543Smrg    {XvSettable | XvGettable, 0x000000,      0xFFFFFF, XV_COLORKEY_NAME},
26909885543Smrg};
27009885543Smrg
27109885543Smrg
27209885543Smrg/**************************************************************************/
27309885543Smrgstatic XF86ImageRec SMI_VideoImages[] =
27409885543Smrg{
27509885543Smrg    XVIMAGE_YUY2,
27609885543Smrg    XVIMAGE_YV12,
27709885543Smrg    XVIMAGE_I420,
27809885543Smrg    {
27909885543Smrg	FOURCC_RV15,			/* id				*/
28009885543Smrg	XvRGB,				/* type				*/
28109885543Smrg	LSBFirst,			/* byte_order			*/
28209885543Smrg	{ 'R', 'V' ,'1', '5',
28309885543Smrg	  0x00, '5',  0x00, 0x00,
28409885543Smrg	  0x00, 0x00, 0x00, 0x00,
28509885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
28609885543Smrg	16,				/* bits_per_pixel		*/
28709885543Smrg	XvPacked,			/* format			*/
28809885543Smrg	1,				/* num_planes			*/
28909885543Smrg	15,				/* depth			*/
29009885543Smrg	0x001F, 0x03E0, 0x7C00,		/* red_mask, green, blue	*/
29109885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
29209885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
29309885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
29409885543Smrg	{ 'R', 'V', 'B' },		/* component_order		*/
29509885543Smrg	XvTopToBottom			/* scaline_order		*/
29609885543Smrg    },
29709885543Smrg    {
29809885543Smrg	FOURCC_RV16,			/* id				*/
29909885543Smrg	XvRGB,				/* type				*/
30009885543Smrg	LSBFirst,			/* byte_order			*/
30109885543Smrg	{ 'R', 'V' ,'1', '6',
30209885543Smrg	  0x00, 0x00, 0x00, 0x00,
30309885543Smrg	  0x00, 0x00, 0x00, 0x00,
30409885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
30509885543Smrg	16,				/* bits_per_pixel		*/
30609885543Smrg	XvPacked,			/* format			*/
30709885543Smrg	1,				/* num_planes			*/
30809885543Smrg	16,				/* depth			*/
30909885543Smrg	0x001F, 0x07E0, 0xF800,		/* red_mask, green, blue	*/
31009885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
31109885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
31209885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
31309885543Smrg	{ 'R', 'V', 'B' },		/* component_order		*/
31409885543Smrg	XvTopToBottom			/* scaline_order		*/
31509885543Smrg    },
31609885543Smrg    {
31709885543Smrg	FOURCC_RV24,			/* id				*/
31809885543Smrg	XvRGB,				/* type				*/
31909885543Smrg	LSBFirst,			/* byte_order			*/
32009885543Smrg	{ 'R', 'V' ,'2', '4',
32109885543Smrg	  0x00, 0x00, 0x00, 0x00,
32209885543Smrg	  0x00, 0x00, 0x00, 0x00,
32309885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
32409885543Smrg	24,				/* bits_per_pixel		*/
32509885543Smrg	XvPacked,			/* format			*/
32609885543Smrg	1,				/* num_planes			*/
32709885543Smrg	24,				/* depth			*/
32809885543Smrg	0x0000FF, 0x00FF00, 0xFF0000,	/* red_mask, green, blue	*/
32909885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
33009885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
33109885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
33209885543Smrg	{ 'R', 'V', 'B' },		/* component_order			*/
33309885543Smrg	XvTopToBottom			/* scaline_order			*/
33409885543Smrg    },
33509885543Smrg    {
33609885543Smrg	FOURCC_RV32,			/* id				*/
33709885543Smrg	XvRGB,				/* type				*/
33809885543Smrg	LSBFirst,			/* byte_order			*/
33909885543Smrg	{ 'R', 'V' ,'3', '2',
34009885543Smrg	  0x00, 0x00, 0x00, 0x00,
34109885543Smrg	  0x00, 0x00, 0x00, 0x00,
34209885543Smrg	  0x00, 0x00, 0x00, 0x00 },	/* guid				*/
34309885543Smrg	32,				/* bits_per_pixel		*/
34409885543Smrg	XvPacked,			/* format			*/
34509885543Smrg	1,				/* num_planes			*/
34609885543Smrg	24,				/* depth			*/
34709885543Smrg	0x0000FF, 0x00FF00, 0xFF0000,	/* red_mask, green, blue	*/
34809885543Smrg	0, 0, 0,			/* y_sample_bits, u, v		*/
34909885543Smrg	0, 0, 0,			/* horz_y_period, u, v		*/
35009885543Smrg	0, 0, 0,			/* vert_y_period, u, v		*/
35109885543Smrg	{ 'R', 'V', 'B' },		/* component_order			*/
35209885543Smrg	XvTopToBottom			/* scaline_order			*/
35309885543Smrg    },
35409885543Smrg};
35509885543Smrg
35609885543Smrg
3577104f784Smrg/**************************************************************************/
3587104f784Smrgstatic XF86ImageRec SMI501_VideoImages[] = {
3597104f784Smrg    XVIMAGE_YUY2,
3607104f784Smrg    XVIMAGE_YV12,
3617104f784Smrg    XVIMAGE_I420,
3627104f784Smrg    {
3637104f784Smrg     FOURCC_RV16,		/* id                                           */
3647104f784Smrg     XvRGB,			/* type                                         */
3657104f784Smrg     LSBFirst,			/* byte_order                           */
3667104f784Smrg     {'R', 'V', '1', '6',
3677104f784Smrg      0x00, 0x00, 0x00, 0x00,
3687104f784Smrg      0x00, 0x00, 0x00, 0x00,
3697104f784Smrg      0x00, 0x00, 0x00, 0x00},	/* guid                                         */
3707104f784Smrg     16,			/* bits_per_pixel                       */
3717104f784Smrg     XvPacked,			/* format                                       */
3727104f784Smrg     1,				/* num_planes                           */
3737104f784Smrg     16,			/* depth                                        */
3747104f784Smrg     0x001F, 0x07E0, 0xF800,	/* red_mask, green, blue        */
3757104f784Smrg     0, 0, 0,			/* y_sample_bits, u, v          */
3767104f784Smrg     0, 0, 0,			/* horz_y_period, u, v          */
3777104f784Smrg     0, 0, 0,			/* vert_y_period, u, v          */
3787104f784Smrg     {'R', 'V', 'B'},		/* component_order                      */
3797104f784Smrg     XvTopToBottom		/* scaline_order                        */
3807104f784Smrg     },
3817104f784Smrg    {
3827104f784Smrg     FOURCC_RV32,		/* id                                           */
3837104f784Smrg     XvRGB,			/* type                                         */
3847104f784Smrg     LSBFirst,			/* byte_order                           */
3857104f784Smrg     {'R', 'V', '3', '2',
3867104f784Smrg      0x00, 0x00, 0x00, 0x00,
3877104f784Smrg      0x00, 0x00, 0x00, 0x00,
3887104f784Smrg      0x00, 0x00, 0x00, 0x00},	/* guid                                         */
3897104f784Smrg     32,			/* bits_per_pixel                       */
3907104f784Smrg     XvPacked,			/* format                                       */
3917104f784Smrg     1,				/* num_planes                           */
3927104f784Smrg     24,			/* depth                                        */
3937104f784Smrg     0x0000FF, 0x00FF00, 0xFF0000,	/* red_mask, green, blue        */
3947104f784Smrg     0, 0, 0,			/* y_sample_bits, u, v          */
3957104f784Smrg     0, 0, 0,			/* horz_y_period, u, v          */
3967104f784Smrg     0, 0, 0,			/* vert_y_period, u, v          */
3977104f784Smrg     {'R', 'V', 'B'},		/* component_order                      */
3987104f784Smrg     XvTopToBottom		/* scaline_order                        */
3997104f784Smrg     },
4007104f784Smrg};
4017104f784Smrg
40209885543Smrg/**************************************************************************/
40309885543Smrg
40409885543Smrg/**
40509885543Smrg * SAA7111 video decoder register values
40609885543Smrg */
40709885543Smrg
40809885543Smrg
40909885543Smrg/** SAA7111 control sequences for selecting one out of four
41009885543Smrg    composite input channels */
41109885543Smrgstatic I2CByte SAA7111CompositeChannelSelect[N_COMPOSITE_CHANNELS][4] = {
41209885543Smrg    { 0x02, 0xC0, 0x09, 0x4A}, /* CVBS AI11 */
41309885543Smrg    { 0x02, 0xC1, 0x09, 0x4A}, /* CVBS AI12 */
41409885543Smrg    { 0x02, 0xC2, 0x09, 0x4A}, /* CVBS AI21 */
41509885543Smrg    { 0x02, 0xC3, 0x09, 0x4A}, /* CVBS AI22 */
41609885543Smrg};
41709885543Smrg
41809885543Smrg
41909885543Smrg/** SAA7111 control sequences for selecting one out of two
42009885543Smrg    s-video input channels */
42109885543Smrgstatic I2CByte SAA7111SVideoChannelSelect[N_SVIDEO_CHANNELS][4] = {
42209885543Smrg    { 0x02, 0xC6, 0x09, 0xCA}, /* Y/C AI11/AI21 */
42309885543Smrg    { 0x02, 0xC7, 0x09, 0xCA}, /* Y/C AI12/AI22 */
42409885543Smrg};
42509885543Smrg
42609885543Smrg
42709885543Smrg/** SAA7111 control sequences for selecting one out of three
42809885543Smrg    video norms */
42909885543Smrgstatic I2CByte SAA7111VideoStd[3][8] = {
43009885543Smrg    {0x06, 108, 0x07, 108, 0x08, 0x09, 0x0E, 0x01}, /* PAL */
43109885543Smrg    {0x06, 107, 0x07, 107, 0x08, 0x49, 0x0E, 0x01}, /* NTSC */
43209885543Smrg    {0x06, 108, 0x07, 108, 0x08, 0x01, 0x0E, 0x51}  /* SECAM */
43309885543Smrg};
43409885543Smrg
43509885543Smrg
43609885543Smrg#if 0
43709885543Smrgstatic I2CByte SAA7110InitData[] =
43809885543Smrg{
43909885543Smrg	/* Configuration */
44009885543Smrg    0x00, 0x4C, 0x01, 0x3C, 0x02, 0x00, 0x03, 0xEF,
44109885543Smrg    0x04, 0xBD, 0x05, 0xE2, 0x06, 0x00, 0x07, 0x00,
44209885543Smrg    0x08, 0xF8, 0x09, 0xF8, 0x0A, 0x60, 0x0B, 0x60,
44309885543Smrg    0x0C, 0x00, 0x0D, 0x80, 0x0E, 0x18, 0x0F, 0xD9,
44409885543Smrg    0x10, 0x00, 0x11, 0x2B, 0x12, 0x40, 0x13, 0x40,
44509885543Smrg    0x14, 0x42, 0x15, 0x1A, 0x16, 0xFF, 0x17, 0xDA,
44609885543Smrg    0x18, 0xE6, 0x19, 0x90, 0x20, 0xD9, 0x21, 0x16,
44709885543Smrg    0x22, 0x40, 0x23, 0x40, 0x24, 0x80, 0x25, 0x40,
44809885543Smrg    0x26, 0x80, 0x27, 0x4F, 0x28, 0xFE, 0x29, 0x01,
44909885543Smrg    0x2A, 0xCF, 0x2B, 0x0F, 0x2C, 0x03, 0x2D, 0x01,
45009885543Smrg    0x2E, 0x83, 0x2F, 0x03, 0x30, 0x40, 0x31, 0x35,
45109885543Smrg    0x32, 0x02, 0x33, 0x8C, 0x34, 0x03,
45209885543Smrg
45309885543Smrg	/* NTSC */
45409885543Smrg    0x11, 0x2B, 0x0F, 0xD9,
45509885543Smrg
45609885543Smrg	/* RCA input connector */
45709885543Smrg    0x06, 0x00, 0x0E, 0x18, 0x20, 0xD9, 0x21, 0x16,
45809885543Smrg    0x22, 0x40, 0x2C, 0x03,
45909885543Smrg
46009885543Smrg};
46109885543Smrg#endif
46209885543Smrg
46309885543Smrgstatic I2CByte SAA7111InitData[] =
46409885543Smrg{
46509885543Smrg    0x11, 0x1D, /* 0D D0=1: automatic colour killer off
46609885543Smrg		   D1=0: DMSD data to YUV output
46709885543Smrg		   D2=1: output enable H/V sync on
46809885543Smrg		   D3=1: output enable YUV data on */
46909885543Smrg    0x02, 0xC0, /* Mode 0 */
47009885543Smrg    0x03, 0x23, /* automatic gain */
47109885543Smrg    0x04, 0x00, /*  */
47209885543Smrg    0x05, 0x00, /*  */
47309885543Smrg    0x06, 108,  /* hor sync begin */
47409885543Smrg    0x07, 108,  /* hor sync stop */
47509885543Smrg    0x08, 0x88, /* sync control:
47609885543Smrg		   D1-0=00: VNOI = normal mode
47709885543Smrg		   D2=0: PLL closed
47809885543Smrg		   D3=1: VTR mode
47909885543Smrg		   D7=1: automatic field detection */
48009885543Smrg    0x09, 0x41, /* 4A luminance control */
48109885543Smrg    0x0A, 0x80, /* brightness = 128 (CCIR level) */
48209885543Smrg    0x0B, 0x40, /* contrast = 1.0 */
48309885543Smrg    0x0C, 0x40, /* crominance = 1.0 (CCIR level) */
48409885543Smrg    0x0D, 0x00, /* hue = 0 */
48509885543Smrg    0x0E, 0x01, /* chroma bandwidth = nominal
48609885543Smrg		   fast colour time constant = nominal
48709885543Smrg		   chrom comp filter on
48809885543Smrg		   colour standard PAL BGHI, NTSC M */
48909885543Smrg    0x10, 0x48, /* luminance delay compensation = 0
49009885543Smrg		   VRLN = 1
49109885543Smrg		   fine pos of hs = 0
49209885543Smrg		   output format = YUV 422 */
49309885543Smrg    0x12, 0x00, /* 20 D5=1: VPO in tristate */
49409885543Smrg    0x13, 0x00,
49509885543Smrg    0x15, 0x00,
49609885543Smrg    0x16, 0x00,
49709885543Smrg    0x17, 0x00,
49809885543Smrg
49909885543Smrg};
50009885543Smrg
50109885543Smrg
50209885543Smrg/**************************************************************************/
50309885543Smrg
50409885543Smrg/**
50509885543Smrg * generates XF86VideoEncoding[i] with video norm norm, video input format
50609885543Smrg * input and video input channel channel
50709885543Smrg */
50809885543Smrgstatic int
50909885543SmrgSMI_AddEncoding(XF86VideoEncodingPtr enc, int i,
51009885543Smrg		int norm, int input, int channel)
51109885543Smrg{
51209885543Smrg    char* norm_string;
51309885543Smrg    char* input_string;
51409885543Smrg    char channel_string[20];
51509885543Smrg
5167104f784Smrg    ENTER();
51709885543Smrg
51809885543Smrg    norm_string = VideoNorms[norm].name;
51909885543Smrg    input_string = VideoInputs[input].name;
52009885543Smrg    sprintf(channel_string, "%d", channel);
52109885543Smrg    enc[i].id     = i;
5227b58d2e0Smrg    enc[i].name   = malloc(strlen(norm_string) +
52309885543Smrg			   strlen(input_string) +
52409885543Smrg			   strlen(channel_string)+3);
5257104f784Smrg    if (NULL == enc[i].name)
5267104f784Smrg	LEAVE(-1);
5277104f784Smrg
52809885543Smrg    enc[i].width  = VideoNorms[norm].Wa;
52909885543Smrg    enc[i].height = VideoNorms[norm].Ha;
53009885543Smrg    enc[i].rate   = VideoNorms[norm].rate;
53109885543Smrg    sprintf(enc[i].name,"%s-%s-%s", norm_string, input_string, channel_string);
53209885543Smrg
5337104f784Smrg    LEAVE(0);
53409885543Smrg}
53509885543Smrg
53609885543Smrg
53709885543Smrg/**
53809885543Smrg * builds XF86VideoEncodings with all legal combinations of video norm,
53909885543Smrg * video input format and video input channel
54009885543Smrg */
54109885543Smrgstatic void
54209885543SmrgSMI_BuildEncodings(SMI_PortPtr p)
54309885543Smrg{
54409885543Smrg    int ch, n;
54509885543Smrg
5467104f784Smrg    ENTER();
54709885543Smrg
54809885543Smrg    /* allocate memory for encoding array */
5497b58d2e0Smrg    p->enc = malloc(sizeof(XF86VideoEncodingRec) * N_ENCODINGS);
55009885543Smrg    if (NULL == p->enc)
55109885543Smrg	goto fail;
55209885543Smrg    memset(p->enc,0,sizeof(XF86VideoEncodingRec) * N_ENCODINGS);
55309885543Smrg    /* allocate memory for video norm array */
5547b58d2e0Smrg    p->norm = malloc(sizeof(int) * N_ENCODINGS);
55509885543Smrg    if (NULL == p->norm)
55609885543Smrg	goto fail;
55709885543Smrg    memset(p->norm,0,sizeof(int) * N_ENCODINGS);
55809885543Smrg    /* allocate memory for video input format array */
5597b58d2e0Smrg    p->input = malloc(sizeof(int) * N_ENCODINGS);
56009885543Smrg    if (NULL == p->input)
56109885543Smrg	goto fail;
56209885543Smrg    memset(p->input,0,sizeof(int) * N_ENCODINGS);
56309885543Smrg    /* allocate memory for video channel number array */
5647b58d2e0Smrg    p->channel = malloc(sizeof(int) * N_ENCODINGS);
56509885543Smrg    if (NULL == p->channel)
56609885543Smrg	goto fail;
56709885543Smrg    memset(p->channel,0,sizeof(int) * N_ENCODINGS);
56809885543Smrg
56909885543Smrg    /* fill arrays */
57009885543Smrg    p->nenc = 0;
57109885543Smrg    for (ch = 0; ch < N_COMPOSITE_CHANNELS; ch++) {
57209885543Smrg	for (n = 0; n < N_VIDEO_NORMS; n++) {
57309885543Smrg	    SMI_AddEncoding(p->enc, p->nenc, n, VID_COMPOSITE, ch);
57409885543Smrg	    p->norm[p->nenc]  = n;
57509885543Smrg	    p->input[p->nenc] = VID_COMPOSITE;
57609885543Smrg	    p->channel[p->nenc] = ch;
57709885543Smrg	    p->nenc++;
57809885543Smrg	}
57909885543Smrg    }
58009885543Smrg    for (ch = 0; ch < N_SVIDEO_CHANNELS; ch++) {
58109885543Smrg	for (n = 0; n < N_VIDEO_NORMS; n++) {
58209885543Smrg	    SMI_AddEncoding(p->enc, p->nenc, n, VID_SVIDEO, ch);
58309885543Smrg	    p->norm[p->nenc]  = n;
58409885543Smrg	    p->input[p->nenc] = VID_SVIDEO;
58509885543Smrg	    p->channel[p->nenc] = ch;
58609885543Smrg	    p->nenc++;
58709885543Smrg	}
58809885543Smrg    }
5897104f784Smrg    LEAVE();
59009885543Smrg
59109885543Smrg fail:
5927b58d2e0Smrg    free(p->input);
59309885543Smrg    p->input = NULL;
5947b58d2e0Smrg    free(p->norm);
59509885543Smrg    p->norm = NULL;
5967b58d2e0Smrg    free(p->channel);
59709885543Smrg    p->channel = NULL;
5987b58d2e0Smrg    free(p->enc);
59909885543Smrg    p->enc = NULL;
60009885543Smrg    p->nenc = 0;
6017104f784Smrg    LEAVE();
60209885543Smrg}
60309885543Smrg
60409885543Smrg
60509885543Smrg/******************************************************************************\
60609885543Smrg**                                                                            **
60709885543Smrg**                  X V E X T E N S I O N   I N T E R F A C E                 **
60809885543Smrg**                                                                            **
60909885543Smrg\******************************************************************************/
61009885543Smrg
61109885543Smrgvoid
61209885543SmrgSMI_InitVideo(ScreenPtr pScreen)
61309885543Smrg{
614b12e5c03Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
61509885543Smrg    XF86VideoAdaptorPtr *ptrAdaptors, *newAdaptors = NULL;
61609885543Smrg    XF86VideoAdaptorPtr newAdaptor = NULL;
61709885543Smrg    int numAdaptors;
61809885543Smrg
6197104f784Smrg    ENTER();
62009885543Smrg
62109885543Smrg    numAdaptors = xf86XVListGenericAdaptors(pScrn, &ptrAdaptors);
62209885543Smrg
6237104f784Smrg    DEBUG("numAdaptors=%d\n", numAdaptors);
62409885543Smrg
6257104f784Smrg    newAdaptor = SMI_SetupVideo(pScreen);
6267104f784Smrg    DEBUG("newAdaptor=%p\n", newAdaptor);
6277104f784Smrg    SMI_InitOffscreenImages(pScreen);
62809885543Smrg
62909885543Smrg    if (newAdaptor != NULL) {
63009885543Smrg        if (numAdaptors == 0) {
63109885543Smrg            numAdaptors = 1;
63209885543Smrg            ptrAdaptors = &newAdaptor;
63309885543Smrg        } else {
6347b58d2e0Smrg            newAdaptors = malloc((numAdaptors + 1) *
63509885543Smrg                    sizeof(XF86VideoAdaptorPtr*));
63609885543Smrg            if (newAdaptors != NULL) {
63709885543Smrg                memcpy(newAdaptors, ptrAdaptors,
63809885543Smrg                        numAdaptors * sizeof(XF86VideoAdaptorPtr));
63909885543Smrg                newAdaptors[numAdaptors++] = newAdaptor;
64009885543Smrg                ptrAdaptors = newAdaptors;
64109885543Smrg            }
64209885543Smrg        }
64309885543Smrg    }
64409885543Smrg
64509885543Smrg    if (numAdaptors != 0) {
6467104f784Smrg        DEBUG("ScreenInit %i\n",numAdaptors);
64709885543Smrg        xf86XVScreenInit(pScreen, ptrAdaptors, numAdaptors);
64809885543Smrg    }
64909885543Smrg
6507b58d2e0Smrg    free(newAdaptors);
65109885543Smrg
6527104f784Smrg    LEAVE();
65309885543Smrg}
65409885543Smrg
65509885543Smrg
65609885543Smrg/*************************************************************************/
65709885543Smrg
65809885543Smrg/*
65909885543Smrg *  Video codec controls
66009885543Smrg */
66109885543Smrg
66209885543Smrg#if 0
66309885543Smrg/**
66409885543Smrg * scales value value of attribute i to range min, max
66509885543Smrg */
66609885543Smrgstatic int
66709885543SmrgScale(int i, int value, int min, int max)
66809885543Smrg{
66909885543Smrg    return min + (value - SMI_VideoAttributes[i].min_value) * (max - min) /
67009885543Smrg	(SMI_VideoAttributes[i].max_value - SMI_VideoAttributes[i].min_value);
67109885543Smrg}
67209885543Smrg#endif
67309885543Smrg/**
67409885543Smrg * sets video decoder attributes channel, encoding, brightness, contrast, saturation, hue
67509885543Smrg */
67609885543Smrgstatic int
67709885543SmrgSetAttr(ScrnInfoPtr pScrn, int i, int value)
67809885543Smrg{
67909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
68009885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
68109885543Smrg
68209885543Smrg    if (i < XV_ENCODING || i > XV_HUE)
68309885543Smrg	return BadMatch;
68409885543Smrg
68509885543Smrg    /* clamps value to attribute range */
68609885543Smrg    value = CLAMP(value, SMI_VideoAttributes[i].min_value,
68709885543Smrg		  SMI_VideoAttributes[i].max_value);
68809885543Smrg
68909885543Smrg    if (i == XV_BRIGHTNESS) {
69009885543Smrg	int my_value = (value <= 128? value + 128 : value - 128);
69109885543Smrg	SetKeyReg(pSmi, 0x5C, 0xEDEDED | (my_value << 24));
69209885543Smrg    } else if (pPort->I2CDev.SlaveAddr == SAA7110) {
69309885543Smrg	return SetAttrSAA7110(pScrn, i, value);
69409885543Smrg    } else if (pPort->I2CDev.SlaveAddr == SAA7111) {
69509885543Smrg	return SetAttrSAA7111(pScrn, i, value);
69609885543Smrg    }
69709885543Smrg#if 0
69809885543Smrg    else {
69909885543Smrg	return XvBadAlloc;
70009885543Smrg    }
70109885543Smrg#endif
70209885543Smrg
70309885543Smrg    return Success;
70409885543Smrg}
70509885543Smrg
70609885543Smrg
70709885543Smrg/**
70809885543Smrg * sets SAA7110 video decoder attributes channel, encoding, brightness, contrast, saturation, hue
70909885543Smrg */
71009885543Smrgstatic int
71109885543SmrgSetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value)
71209885543Smrg{
71309885543Smrg    /* not supported */
71409885543Smrg    return XvBadAlloc;
71509885543Smrg}
71609885543Smrg
71709885543Smrg
71809885543Smrg/**
71909885543Smrg * sets SAA7111 video decoder attributes channel, encoding,
72009885543Smrg * brightness, contrast, saturation, hue
72109885543Smrg */
72209885543Smrgstatic int
72309885543SmrgSetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value)
72409885543Smrg{
72509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
72609885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
72709885543Smrg
72809885543Smrg    if (i == XV_ENCODING) {
72909885543Smrg	int norm;
73009885543Smrg	int input;
73109885543Smrg	int channel;
73209885543Smrg	norm = pPort->norm[value];
73309885543Smrg	input = pPort->input[value];
73409885543Smrg	channel = pPort->channel[value];
73509885543Smrg
7367104f784Smrg	DEBUG("SetAttribute XV_ENCODING: %d. norm=%d input=%d channel=%d\n",
7377104f784Smrg	      value, norm, input, channel);
73809885543Smrg
73909885543Smrg	/* set video norm */
74009885543Smrg	if (!xf86I2CWriteVec(&(pPort->I2CDev), SAA7111VideoStd[norm],
74109885543Smrg			     ENTRIES(SAA7111VideoStd[norm]) / 2)) {
74209885543Smrg	    return XvBadAlloc;
74309885543Smrg	}
74409885543Smrg	/* set video input format and channel */
74509885543Smrg	if (input == VID_COMPOSITE) {
74609885543Smrg	    if (!xf86I2CWriteVec(&(pPort->I2CDev),
74709885543Smrg				 SAA7111CompositeChannelSelect[channel],
74809885543Smrg				 ENTRIES(SAA7111CompositeChannelSelect[channel]) / 2)) {
74909885543Smrg		return XvBadAlloc;
75009885543Smrg	    }
75109885543Smrg	} else {
75209885543Smrg	    if (!xf86I2CWriteVec(&(pPort->I2CDev),
75309885543Smrg				 SAA7111SVideoChannelSelect[channel],
75409885543Smrg				 ENTRIES(SAA7111SVideoChannelSelect[channel]) / 2)) {
75509885543Smrg		return XvBadAlloc;
75609885543Smrg	    }
75709885543Smrg	}
75809885543Smrg    } else if (i >= XV_CAPTURE_BRIGHTNESS && i <= XV_HUE) {
75909885543Smrg	int slave_adr = 0;
76009885543Smrg
76109885543Smrg	switch (i) {
76209885543Smrg
76309885543Smrg	case XV_CAPTURE_BRIGHTNESS:
7647104f784Smrg	    DEBUG("SetAttribute XV_BRIGHTNESS: %d\n", value);
76509885543Smrg	    slave_adr = 0x0a;
76609885543Smrg	    break;
76709885543Smrg
76809885543Smrg	case XV_CONTRAST:
7697104f784Smrg	    DEBUG("SetAttribute XV_CONTRAST: %d\n", value);
77009885543Smrg	    slave_adr = 0x0b;
77109885543Smrg	    break;
77209885543Smrg
77309885543Smrg	case XV_SATURATION:
7747104f784Smrg	    DEBUG("SetAttribute XV_SATURATION: %d\n", value);
77509885543Smrg	    slave_adr = 0x0c;
77609885543Smrg	    break;
77709885543Smrg
77809885543Smrg	case XV_HUE:
7797104f784Smrg	    DEBUG("SetAttribute XV_HUE: %d\n", value);
78009885543Smrg	    slave_adr = 0x0d;
78109885543Smrg	    break;
78209885543Smrg
78309885543Smrg	default:
78409885543Smrg	    return XvBadAlloc;
78509885543Smrg	}
78609885543Smrg	if (!xf86I2CWriteByte(&(pPort->I2CDev), slave_adr, (value & 0xff)))
78709885543Smrg	    return XvBadAlloc;
78809885543Smrg    } else {
78909885543Smrg	return BadMatch;
79009885543Smrg    }
79109885543Smrg
79209885543Smrg    /* debug: show registers */
79309885543Smrg    {
79409885543Smrg	I2CByte i2c_bytes[32];
79509885543Smrg	int i;
79609885543Smrg	xf86I2CReadBytes(&(pPort->I2CDev), 0, i2c_bytes, 32);
7977104f784Smrg	DEBUG("SAA7111 Registers\n");
79809885543Smrg	for (i=0; i<32; i++) {
7997104f784Smrg	    DEBUG("%02X=%02X ", i, i2c_bytes[i]);
8007104f784Smrg	    if ((i&7) == 7) DEBUG("\n");
80109885543Smrg	}
80209885543Smrg    }
80309885543Smrg
80409885543Smrg    return Success;
80509885543Smrg}
80609885543Smrg
80709885543Smrg
80809885543Smrg/******************************************************************************\
80909885543Smrg**									      **
81009885543Smrg**	V I D E O   M A N A G E M E N T					      **
81109885543Smrg**									      **
81209885543Smrg\******************************************************************************/
81309885543Smrg
81409885543Smrgstatic XF86VideoAdaptorPtr
81509885543SmrgSMI_SetupVideo(ScreenPtr pScreen)
81609885543Smrg{
817b12e5c03Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
81809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
81909885543Smrg    SMI_PortPtr smiPortPtr;
82009885543Smrg    XF86VideoAdaptorPtr ptrAdaptor;
82109885543Smrg
8227104f784Smrg    ENTER();
82309885543Smrg
8247b58d2e0Smrg    ptrAdaptor = calloc(1, sizeof(XF86VideoAdaptorRec) +
82509885543Smrg		 sizeof(DevUnion) + sizeof(SMI_PortRec));
8267104f784Smrg    if (ptrAdaptor == NULL)
8277104f784Smrg	LEAVE(NULL);
82809885543Smrg
82909885543Smrg    ptrAdaptor->type = XvInputMask
83009885543Smrg#if SMI_USE_CAPTURE
83109885543Smrg		     | XvOutputMask
83209885543Smrg		     | XvVideoMask
83309885543Smrg#endif
83409885543Smrg		     | XvImageMask
83509885543Smrg		     | XvWindowMask
83609885543Smrg		     ;
83709885543Smrg
8387104f784Smrg    ptrAdaptor->flags = VIDEO_OVERLAID_IMAGES;
8397104f784Smrg    if (IS_MSOC(pSmi)) {
8407104f784Smrg	ptrAdaptor->name = "Silicon Motion MSOC Series Video Engine";
8417104f784Smrg    }
8427104f784Smrg    else
8437104f784Smrg	ptrAdaptor->name = "Silicon Motion Lynx Series Video Engine";
84409885543Smrg
84509885543Smrg    ptrAdaptor->nPorts = 1;
84609885543Smrg    ptrAdaptor->pPortPrivates = (DevUnion*) &ptrAdaptor[1];
84709885543Smrg    ptrAdaptor->pPortPrivates[0].ptr = (pointer) &ptrAdaptor->pPortPrivates[1];
84809885543Smrg
84909885543Smrg    smiPortPtr = (SMI_PortPtr) ptrAdaptor->pPortPrivates[0].ptr;
85009885543Smrg
85109885543Smrg    SMI_BuildEncodings(smiPortPtr);
85209885543Smrg    ptrAdaptor->nEncodings = smiPortPtr->nenc;
85309885543Smrg    ptrAdaptor->pEncodings = smiPortPtr->enc;
85409885543Smrg#if 0
85509885543Smrg    /* aaa whats this? */
85609885543Smrg	for (i = 0; i < nElems(SMI_VideoEncodings); i++)
85709885543Smrg	{
85809885543Smrg		SMI_VideoEncodings[i].width = pSmi->lcdWidth;
85909885543Smrg		SMI_VideoEncodings[i].height = pSmi->lcdHeight;
86009885543Smrg	}
86109885543Smrg#endif
86209885543Smrg
86309885543Smrg    ptrAdaptor->nFormats = nElems(SMI_VideoFormats);
86409885543Smrg    ptrAdaptor->pFormats = SMI_VideoFormats;
86509885543Smrg
86609885543Smrg    ptrAdaptor->nAttributes = nElems(SMI_VideoAttributes);
86709885543Smrg    ptrAdaptor->pAttributes = SMI_VideoAttributes;
86809885543Smrg
8697104f784Smrg    if (IS_MSOC(pSmi)) {
8707104f784Smrg	ptrAdaptor->nImages = nElems(SMI501_VideoImages);
8717104f784Smrg	ptrAdaptor->pImages = SMI501_VideoImages;
8727104f784Smrg    }
8737104f784Smrg    else {
8747104f784Smrg	ptrAdaptor->nImages = nElems(SMI_VideoImages);
8757104f784Smrg	ptrAdaptor->pImages = SMI_VideoImages;
8767104f784Smrg    }
87709885543Smrg
87809885543Smrg#if SMI_USE_CAPTURE
8797104f784Smrg    if (pSmi->Chipset == SMI_COUGAR3DR || IS_MSOC(pSmi))
88009885543Smrg	ptrAdaptor->PutVideo = NULL;
88109885543Smrg    else
88209885543Smrg	ptrAdaptor->PutVideo = SMI_PutVideo;
88309885543Smrg    ptrAdaptor->PutStill = NULL;
88409885543Smrg    ptrAdaptor->GetVideo = NULL;
88509885543Smrg    ptrAdaptor->GetStill = NULL;
88609885543Smrg#else
88709885543Smrg    ptrAdaptor->PutVideo = NULL;
88809885543Smrg    ptrAdaptor->PutStill = NULL;
88909885543Smrg    ptrAdaptor->GetVideo = NULL;
89009885543Smrg    ptrAdaptor->GetStill = NULL;
89109885543Smrg#endif
89209885543Smrg    ptrAdaptor->StopVideo = SMI_StopVideo;
89309885543Smrg    ptrAdaptor->SetPortAttribute = SMI_SetPortAttribute;
89409885543Smrg    ptrAdaptor->GetPortAttribute = SMI_GetPortAttribute;
89509885543Smrg    ptrAdaptor->QueryBestSize = SMI_QueryBestSize;
89609885543Smrg    ptrAdaptor->PutImage = SMI_PutImage;
89709885543Smrg    ptrAdaptor->QueryImageAttributes = SMI_QueryImageAttributes;
89809885543Smrg
89909885543Smrg    smiPortPtr->Attribute[XV_COLORKEY] = pSmi->videoKey;
90009885543Smrg    smiPortPtr->Attribute[XV_INTERLACED] = pSmi->interlaced;
90109885543Smrg    smiPortPtr->videoStatus = 0;
90209885543Smrg
90309885543Smrg#if 0
90409885543Smrg    /* aaa does not work ? */
90509885543Smrg    if (xf86I2CProbeAddress(pSmi->I2C, SAA7111))
9067104f784Smrg        LEAVE(NULL);
9077104f784Smrg    DEBUG("SAA7111 detected\n");
90809885543Smrg#endif
90909885543Smrg
91009885543Smrg    smiPortPtr->I2CDev.DevName = "SAA 7111A";
91109885543Smrg    smiPortPtr->I2CDev.SlaveAddr = SAA7111;
91209885543Smrg    smiPortPtr->I2CDev.pI2CBus = pSmi->I2C;
91309885543Smrg
9147104f784Smrg
9157104f784Smrg    if (!IS_MSOC(pSmi) && xf86I2CDevInit(&(smiPortPtr->I2CDev))) {
91609885543Smrg
91709885543Smrg	if (xf86I2CWriteVec(&(smiPortPtr->I2CDev), SAA7111InitData, ENTRIES(SAA7111InitData) / 2)) {
91809885543Smrg	    xvEncoding   = MAKE_ATOM(XV_ENCODING_NAME);
91909885543Smrg	    xvHue        = MAKE_ATOM(XV_HUE_NAME);
92009885543Smrg	    xvSaturation = MAKE_ATOM(XV_SATURATION_NAME);
92109885543Smrg	    xvContrast   = MAKE_ATOM(XV_CONTRAST_NAME);
92209885543Smrg
92309885543Smrg	    xvInterlaced = MAKE_ATOM(XV_INTERLACED_NAME);
9247104f784Smrg	    DEBUG("SAA7111 intialized\n");
92509885543Smrg
92609885543Smrg	} else {
92709885543Smrg	    xf86DestroyI2CDevRec(&(smiPortPtr->I2CDev),FALSE);
92809885543Smrg	    smiPortPtr->I2CDev.SlaveAddr = 0;
92909885543Smrg	}
93009885543Smrg    } else
93109885543Smrg	smiPortPtr->I2CDev.SlaveAddr = 0;
93209885543Smrg
93309885543Smrg#if defined(REGION_NULL)
93409885543Smrg    REGION_NULL(pScreen, &smiPortPtr->clip);
93509885543Smrg#else
93609885543Smrg    REGION_INIT(pScreen, &smiPortPtr->clip, NullBox, 0);
93709885543Smrg#endif
93809885543Smrg
93909885543Smrg    pSmi->ptrAdaptor = ptrAdaptor;
94009885543Smrg    pSmi->BlockHandler = pScreen->BlockHandler;
94109885543Smrg    pScreen->BlockHandler = SMI_BlockHandler;
94209885543Smrg
94309885543Smrg    xvColorKey   = MAKE_ATOM(XV_COLORKEY_NAME);
94409885543Smrg    xvBrightness = MAKE_ATOM(XV_BRIGHTNESS_NAME);
94509885543Smrg    xvCapBrightness = MAKE_ATOM(XV_CAPTURE_BRIGHTNESS_NAME);
94609885543Smrg
94709885543Smrg    SMI_ResetVideo(pScrn);
9487104f784Smrg
9497104f784Smrg    LEAVE(ptrAdaptor);
95009885543Smrg}
95109885543Smrg
95209885543Smrg
95309885543Smrgstatic void
95409885543SmrgSMI_ResetVideo(ScrnInfoPtr pScrn)
95509885543Smrg{
95609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
95709885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
95809885543Smrg    int r, g, b;
95909885543Smrg
9607104f784Smrg    ENTER();
96109885543Smrg
96209885543Smrg    SetAttr(pScrn, XV_ENCODING, 0);     /* Encoding = pal-composite-0 */
96309885543Smrg    SetAttr(pScrn, XV_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */
96409885543Smrg    SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */
96509885543Smrg    SetAttr(pScrn, XV_CONTRAST, 71);    /* Contrast = 71 (CCIR level) */
96609885543Smrg    SetAttr(pScrn, XV_SATURATION, 64);  /* Color saturation = 64 (CCIR level) */
96709885543Smrg    SetAttr(pScrn, XV_HUE, 0);          /* Hue = 0 */
96809885543Smrg
96909885543Smrg    switch (pScrn->depth) {
97009885543Smrg    case 8:
97109885543Smrg	SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0x00FF);
97209885543Smrg	SetKeyReg(pSmi, FPR08, 0);
97309885543Smrg	break;
97409885543Smrg    case 15:
97509885543Smrg    case 16:
97609885543Smrg	SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0xFFFF);
97709885543Smrg	SetKeyReg(pSmi, FPR08, 0);
97809885543Smrg	break;
97909885543Smrg    default:
98009885543Smrg        r = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.red) >> pScrn->offset.red;
98109885543Smrg        g = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.green) >> pScrn->offset.green;
98209885543Smrg        b = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.blue) >> pScrn->offset.blue;
98309885543Smrg	SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3));
98409885543Smrg	SetKeyReg(pSmi, FPR08, 0);
98509885543Smrg	break;
98609885543Smrg    }
98709885543Smrg
98809885543Smrg    SetKeyReg(pSmi, FPR5C, 0xEDEDED | (pPort->Attribute[XV_BRIGHTNESS] << 24));
98909885543Smrg
9907104f784Smrg    LEAVE();
99109885543Smrg}
99209885543Smrg
99309885543Smrg
99409885543Smrg#if SMI_USE_CAPTURE
99509885543Smrgstatic int
99609885543SmrgSMI_PutVideo(
99709885543Smrg	ScrnInfoPtr	pScrn,
99809885543Smrg	short		vid_x,
99909885543Smrg	short		vid_y,
100009885543Smrg	short		drw_x,
100109885543Smrg	short		drw_y,
100209885543Smrg	short		vid_w,
100309885543Smrg	short		vid_h,
100409885543Smrg	short		drw_w,
100509885543Smrg	short		drw_h,
100609885543Smrg	RegionPtr	clipBoxes,
100709885543Smrg	pointer		data,
100809885543Smrg	DrawablePtr	pDraw
100909885543Smrg)
101009885543Smrg{
101109885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
101209885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
101309885543Smrg    CARD32 vid_pitch, vid_address;
101409885543Smrg    CARD32 vpr00, cpr00;
101509885543Smrg    int xscale, yscale;
101609885543Smrg    BoxRec dstBox;
101709885543Smrg    INT32 x1, y1, x2, y2;
101809885543Smrg    int norm;
101909885543Smrg    int size, width, height, fbPitch;
102009885543Smrg    int top, left;
10217104f784Smrg    xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn);
10227104f784Smrg    xf86CrtcPtr crtc;
102309885543Smrg
10247104f784Smrg    ENTER();
102509885543Smrg
10267104f784Smrg    DEBUG("Interlaced Video %d\n", pPort->Attribute[XV_INTERLACED]);
102709885543Smrg
102809885543Smrg    if (!pPort->Attribute[XV_INTERLACED]) {
102909885543Smrg	/* no interlace: lines will be doubled */
103009885543Smrg	vid_h /= 2;
103109885543Smrg    }
103209885543Smrg
103309885543Smrg    /* field start aaa*/
103409885543Smrg    norm = pPort->norm[pPort->Attribute[XV_ENCODING]];
103509885543Smrg    vid_x += VideoNorms[norm].HStart;
103609885543Smrg    vid_y += VideoNorms[norm].VStart;
103709885543Smrg    /* only even values allowed (UV-phase) */
103809885543Smrg    vid_x &= ~1;
103909885543Smrg
10407104f784Smrg    DEBUG("vid_x=%d vid_y=%d drw_x=%d drw_y=%d  "
10417104f784Smrg	  "vid_w=%d vid_h=%d drw_w=%d drw_h=%d\n",
10427104f784Smrg	  vid_x, vid_y, drw_x, drw_y, vid_w, vid_h, drw_w, drw_h);
104309885543Smrg
104409885543Smrg    x1 = vid_x;
104509885543Smrg    y1 = vid_y;
104609885543Smrg    x2 = vid_x + vid_w;
104709885543Smrg    y2 = vid_y + vid_h;
104809885543Smrg
104909885543Smrg    width = vid_w;
105009885543Smrg    height = vid_h;
105109885543Smrg
105209885543Smrg    dstBox.x1 = drw_x;
105309885543Smrg    dstBox.y1 = drw_y;
105409885543Smrg    dstBox.x2 = drw_x + drw_w;
105509885543Smrg    dstBox.y2 = drw_y + drw_h;
105609885543Smrg
10577104f784Smrg    if(!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
10587104f784Smrg	LEAVE(Success);
10597104f784Smrg
10607b58d2e0Smrg    if (crtc != crtcConf->crtc[0])
10617104f784Smrg	LEAVE(Success);
106209885543Smrg
10637104f784Smrg    /* Transform dstBox to the CRTC coordinates */
10647104f784Smrg    dstBox.x1 -= crtc->x;
10657104f784Smrg    dstBox.y1 -= crtc->y;
10667104f784Smrg    dstBox.x2 -= crtc->x;
10677104f784Smrg    dstBox.y2 -= crtc->y;
106809885543Smrg
10697104f784Smrg    DEBUG("Clip: x1=%d y1=%d x2=%d y2=%d\n",  x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16);
107009885543Smrg
107109885543Smrg    vid_pitch = (vid_w * 2 + 7) & ~7;
107209885543Smrg
107309885543Smrg    vpr00 = READ_VPR(pSmi, 0x00) & ~0x0FF000FF;
107409885543Smrg    cpr00 = READ_CPR(pSmi, 0x00) & ~0x000FFF00;
107509885543Smrg
107609885543Smrg    /* vpr00:
107709885543Smrg       Bit 2..0   = 6: Video Window I Format                    = YUV4:2:2
107809885543Smrg       Bit 3      = 1: Video Window I Enable                    = enabled
107909885543Smrg       Bit 4      = 0: Video Window I YUV Averaging             = disabled
108009885543Smrg       Bit 5      = 0: Video Window I Hor. Replication          = disabled
108109885543Smrg       Bit 6      = 0: Video Window I data doubling             = disabled
108209885543Smrg       Bit 14..8  = 0: Video Window II                          = disabled
108309885543Smrg       Bit 18..16 = 0: Graphics Data Format                     = 8-bit index
108409885543Smrg       Bit 19     = 0: Top Video Window Select                  = window I
108509885543Smrg       Bit 20     = 1: Color Key for Window I                   = enabled
108609885543Smrg       Bit 21     = 0: Vertical Interpolation                   = s. below
108709885543Smrg       Bit 22     = 0: Flicker Reduction for TV Modes           = disabled
108809885543Smrg       Bit 23     = 0: Fixed Vertical Interpolation             = disabled
108909885543Smrg       Bit 24     = 1: Select Video Window I Source Addr        =
109009885543Smrg       Bit 25     = 0: Enable V0FIFO to fetch 8-Bit color data  = disabled
109109885543Smrg       Bit 26     = 0:
109209885543Smrg       Bit 27     = 1: Color Key for Window II                  = disabled
109309885543Smrg       Bit 31..28 = reserved
109409885543Smrg    */
109509885543Smrg    if (pPort->Attribute[XV_INTERLACED]) {
109609885543Smrg	/*
109709885543Smrg	  Bit 21     = 0: Vertical Interpolation                   = disabled
109809885543Smrg	  Bit 24     = 0: Select Video Window I Source Addr        = 0
109909885543Smrg	*/
110009885543Smrg	vpr00 |= 0x0010000E;
110109885543Smrg    } else {
110209885543Smrg	/*
1103e4f6584cSmrg	  Bit 21     = 1: Vertical Interpolation                   = enabled
110409885543Smrg	  Bit 24     = 1: Select Video Window I Source Addr        = 1
110509885543Smrg	  1= Video window I source addr = capture port buffer ?
110609885543Smrg	*/
110709885543Smrg	vpr00 |= 0x0130000E;
110809885543Smrg    }
110909885543Smrg
111009885543Smrg    /* cpr00:
111109885543Smrg       Bit 0      = 1: Video Capture Enable                     = enabled
111209885543Smrg       Bit 8      = 0: Capture Control                          = continous
111309885543Smrg       Bit 9      = 0: Double Buffer Enable                     = s. below
111409885543Smrg       Bit 10     = 0: Interlace Data Capture                   = s. below
111509885543Smrg       Bit 13..11 = 0: Frame Skip Enable                        = s. below
111609885543Smrg       Bit 15..14 = 0: Video Capture Input Format               = YUV4:2:2
111709885543Smrg       Bit 17..16 = 0: Enable Hor. Reduction                    = s. below
111809885543Smrg       Bit 19..18 = 0: Enable Vert. Reduction                   = s. below
111909885543Smrg       Bit 21..20 = 0: Enable Hor. Filtering                    = s. below
112009885543Smrg       Bit 22     = 0: HREF Polarity                            = high active
112109885543Smrg       Bit 23     = 0: VREF Polarity                            = high active
112209885543Smrg       Bit 24     = 1: Field Detection Method VSYNC edge        = rising
112309885543Smrg    */
112409885543Smrg    if (pPort->Attribute[XV_INTERLACED]) {
112509885543Smrg	/*
112609885543Smrg	  Bit 9      = 1: Double Buffer Enable                  = enabled
112709885543Smrg	  Bit 10     = 1: Interlace Data Capture                = enabled
112809885543Smrg	  Bit 13..11 = 0: Frame Skip Enable                     = no skip
112909885543Smrg	*/
113009885543Smrg	cpr00 |= 0x01000601;
113109885543Smrg    } else {
113209885543Smrg	/*
113309885543Smrg	  Bit 9      = 0: Double Buffer Enable                  = disabled
113409885543Smrg	  Bit 10     = 0: Interlace Data Capture                = disabled
113509885543Smrg	  Bit 13..11 = 010: Frame Skip Enable                   = skip every other frame
113609885543Smrg	*/
11377104f784Smrg	cpr00 |= 0x01001001;
113809885543Smrg    }
113909885543Smrg
114009885543Smrg    if (pSmi->ByteSwap)
114109885543Smrg	cpr00 |= 0x00004000;
114209885543Smrg
11437104f784Smrg    fbPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15;
114409885543Smrg
114509885543Smrg    if (vid_w <= drw_w) {
114609885543Smrg	xscale = (256 * vid_w / drw_w) & 0xFF;
114709885543Smrg    } else if (vid_w / 2 <= drw_w) {
114809885543Smrg	xscale = (128 * vid_w / drw_w) & 0xFF;
114909885543Smrg	width /= 2;
115009885543Smrg	vid_pitch /= 2;
115109885543Smrg	cpr00 |= 0x00010000;
115209885543Smrg    } else if (vid_w / 4 <= drw_w) {
115309885543Smrg	xscale = (64 * vid_w / drw_w) & 0xFF;
115409885543Smrg	width /= 4;
115509885543Smrg	vid_pitch /= 4;
115609885543Smrg	cpr00 |= 0x00020000;
115709885543Smrg    } else {
115809885543Smrg	xscale = 0;
115909885543Smrg	width /= 4;
116009885543Smrg	vid_pitch /= 4;
116109885543Smrg	cpr00 |= 0x00020000;
116209885543Smrg    }
116309885543Smrg
116409885543Smrg    if (vid_h <= drw_h) {
116509885543Smrg	yscale = (256 * vid_h / drw_h) & 0xFF;
116609885543Smrg    } else if (vid_h / 2 <= drw_h) {
116709885543Smrg	yscale = (128 * vid_h / drw_h) & 0xFF;
116809885543Smrg	height /= 2;
116909885543Smrg	cpr00 |= 0x00040000;
117009885543Smrg    } else if (vid_h / 4 <= drw_h) {
117109885543Smrg	yscale = (64 * vid_h / drw_h) & 0xFF;
117209885543Smrg	height /= 4;
117309885543Smrg	cpr00 |= 0x00080000;
117409885543Smrg    } else {
117509885543Smrg	yscale = 0;
117609885543Smrg	height /= 4;
117709885543Smrg	cpr00 |= 0x00080000;
117809885543Smrg    }
117909885543Smrg
118009885543Smrg    do {
118109885543Smrg	size = vid_pitch * height;
11827104f784Smrg	DEBUG("SMI_AllocateMemory: vid_pitch=%d height=%d size=%d\n",
11837104f784Smrg	      vid_pitch, height, size);
118409885543Smrg	pPort->video_offset = SMI_AllocateMemory(pScrn, &pPort->video_memory, size);
118509885543Smrg        if (pPort->video_offset == 0) {
118609885543Smrg	    if ((cpr00 & 0x000C0000) == 0) {
118709885543Smrg		/* height -> 1/2 height */
118809885543Smrg		yscale = (128 * vid_h / drw_h) & 0xFF;
118909885543Smrg		height = vid_h / 2;
119009885543Smrg		cpr00 |= 0x00040000;
119109885543Smrg	    } else if (cpr00 & 0x00040000) {
119209885543Smrg		/* 1/2 height -> 1/4 height */
119309885543Smrg		yscale = (64 * vid_h / drw_h) & 0xFF;
119409885543Smrg		height = vid_h / 4;
119509885543Smrg		cpr00 ^= 0x000C0000;
119609885543Smrg	    } else {
119709885543Smrg		/* 1/4 height */
119809885543Smrg		if ((cpr00 & 0x00030000) == 0) {
119909885543Smrg		    /* width -> 1/2 width */
120009885543Smrg		    xscale = (128 * vid_w / drw_w) & 0xFF;
120109885543Smrg		    width = vid_w / 2;
120209885543Smrg		    cpr00 |= 0x00010000;
120309885543Smrg		} else if (cpr00 & 0x00010000) {
120409885543Smrg		    /* 1/2 width -> 1/4 width */
120509885543Smrg		    xscale = (64 * vid_w / drw_w) & 0xFF;
120609885543Smrg		    width = vid_w / 4;
120709885543Smrg		    cpr00 ^= 0x00030000;
120809885543Smrg		} else {
12097104f784Smrg		    DEBUG("allocate error\n");
12107104f784Smrg		    LEAVE(BadAlloc);
121109885543Smrg		}
121209885543Smrg	    }
121309885543Smrg	}
121409885543Smrg    } while (pPort->video_offset == 0);
121509885543Smrg
12167104f784Smrg    DEBUG("xscale==%d yscale=%d width=%d height=%d\n",
12177104f784Smrg	  xscale, yscale, width, height);
121809885543Smrg
121909885543Smrg    /* aaa whats this                     ----------------------v ?
122009885543Smrg    vid_address = (pPort->area->box.y1 * fbPitch) + ((y1 >> 16) * vid_pitch);*/
122109885543Smrg    vid_address = pPort->video_offset;
122209885543Smrg
12237104f784Smrg    DEBUG("test RegionsEqual\n");
122409885543Smrg    if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes))
122509885543Smrg    {
122609885543Smrg	DEBUG((VERBLEV, "RegionCopy\n"));
122709885543Smrg        REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes);
12287104f784Smrg	DEBUG("FillKey\n");
122909885543Smrg	xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes);
123009885543Smrg
123109885543Smrg    }
123209885543Smrg
123309885543Smrg    left = x1 >> 16;
123409885543Smrg    top = y1 >> 16;
123509885543Smrg    width = (x2 - x1) >> 16;
123609885543Smrg    height = (y2 - y1) >> 16;
123709885543Smrg
12387104f784Smrg    if (!IS_MSOC(pSmi))
12397104f784Smrg	VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA,
12407104f784Smrg		      0x21,
12417104f784Smrg		      VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA,
12427104f784Smrg				   0x21) & ~0x04);
124309885543Smrg    WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) | 0x00200000);
124409885543Smrg    /* Video Window I Left and Top Boundaries */
124509885543Smrg    WRITE_VPR(pSmi, 0x14, dstBox.x1 + (dstBox.y1 << 16));
124609885543Smrg    /* Video Window I Right and Bottom Boundaries */
124709885543Smrg    WRITE_VPR(pSmi, 0x18, dstBox.x2 + (dstBox.y2 << 16));
124809885543Smrg    /* Video Window I Source Width and Offset */
124909885543Smrg    WRITE_VPR(pSmi, 0x20, (vid_pitch / 8) + ((vid_pitch / 8) << 16));
125009885543Smrg    /* Video Window I Stretch Factor */
125109885543Smrg    WRITE_VPR(pSmi, 0x24, (xscale << 8) + yscale);
125209885543Smrg
125309885543Smrg    if (pPort->Attribute[XV_INTERLACED]) {
125409885543Smrg	/* Video Window II Left and Top Boundaries */
125509885543Smrg	WRITE_VPR(pSmi, 0x28, dstBox.x1 + (dstBox.y1 << 16));
125609885543Smrg	/* Video Window II Right and Bottom Boundaries */
125709885543Smrg	WRITE_VPR(pSmi, 0x2C, dstBox.x2 + (dstBox.y2 << 16));
125809885543Smrg	/* Video Window II Source Width and Offset */
125909885543Smrg	WRITE_VPR(pSmi, 0x34, (vid_pitch / 8) + ((vid_pitch / 8) << 16));
126009885543Smrg	/* Video Window II Stretch Factor */
126109885543Smrg	WRITE_VPR(pSmi, 0x38, (xscale << 8) + yscale);
126209885543Smrg
126309885543Smrg	/* Video Window I Source Start Address */
126409885543Smrg	WRITE_VPR(pSmi, 0x1C, vid_address / 8);
126509885543Smrg	/* Video Window II Source Start Address */
126609885543Smrg	WRITE_VPR(pSmi, 0x30, vid_address / 8);
126709885543Smrg
126809885543Smrg	/* Video Window I Source Start Address */
126909885543Smrg	WRITE_VPR(pSmi, 0x48, vid_address / 8);
127009885543Smrg	/* Video Window II Source Start Address */
127109885543Smrg	WRITE_VPR(pSmi, 0x4C, vid_address / 8 + vid_pitch / 8);
127209885543Smrg
127309885543Smrg	/* Video Source Clipping Control */
127409885543Smrg	WRITE_CPR(pSmi, 0x04, left + ((top/2) << 16));
127509885543Smrg	/* Video Source Capture Size Control */
127609885543Smrg	WRITE_CPR(pSmi, 0x08, width + ((height/2) << 16));
127709885543Smrg	/* Capture Port Buffer I Source Start Address */
127809885543Smrg	WRITE_CPR(pSmi, 0x0C, vid_address / 8);
127909885543Smrg	/* Capture Port Buffer II Source Start Address */
128009885543Smrg	WRITE_CPR(pSmi, 0x10, vid_address / 8 + vid_pitch / 8);
128109885543Smrg	/* Capture Port Source Offset Address */
128209885543Smrg	WRITE_CPR(pSmi, 0x14, 2*(vid_pitch / 8) + ((2*(vid_pitch / 8)) << 16));
128309885543Smrg    } else {
128409885543Smrg	/* Video Source Clipping Control */
128509885543Smrg	WRITE_CPR(pSmi, 0x04, left + (top << 16));
128609885543Smrg	/* Video Source Capture Size Control */
128709885543Smrg	WRITE_CPR(pSmi, 0x08, width + (height << 16));
128809885543Smrg	/* Capture Port Buffer I Source Start Address */
128909885543Smrg	WRITE_CPR(pSmi, 0x0C, vid_address / 8);
129009885543Smrg	/* Capture Port Buffer II Source Start Address */
129109885543Smrg	WRITE_CPR(pSmi, 0x10, vid_address / 8);
129209885543Smrg	/* Capture Port Source Offset Address */
129309885543Smrg	WRITE_CPR(pSmi, 0x14, (vid_pitch / 8) + ((vid_pitch / 8) << 16));
129409885543Smrg    }
129509885543Smrg
129609885543Smrg    WRITE_CPR(pSmi, 0x00, cpr00);
129709885543Smrg    WRITE_VPR(pSmi, 0x00, vpr00);
129809885543Smrg
129909885543Smrg    pPort->videoStatus = CLIENT_VIDEO_ON;
13007104f784Smrg    DEBUG("SMI_PutVideo success\n");
13017104f784Smrg
13027104f784Smrg    LEAVE(Success);
130309885543Smrg}
130409885543Smrg#endif
130509885543Smrg
130609885543Smrg
130709885543Smrgstatic void
130809885543SmrgSMI_StopVideo(
130909885543Smrg	ScrnInfoPtr	pScrn,
131009885543Smrg	pointer		data,
131109885543Smrg	Bool		shutdown
131209885543Smrg)
131309885543Smrg{
131409885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
131509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
131609885543Smrg
13177104f784Smrg    ENTER();
131809885543Smrg
131909885543Smrg    REGION_EMPTY(pScrn->pScreen, &pPort->clip);
132009885543Smrg
132109885543Smrg    if (shutdown) {
132209885543Smrg	if (pPort->videoStatus & CLIENT_VIDEO_ON) {
13237104f784Smrg	    if (pSmi->Chipset == SMI_COUGAR3DR)
132409885543Smrg		WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE));
13257104f784Smrg	    else if (IS_MSOC(pSmi))
13267104f784Smrg		WRITE_DCR(pSmi, 0x0040, READ_DCR(pSmi, 0x0040) & ~0x00000004);
13277104f784Smrg	    else
132809885543Smrg		WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x01000008);
132909885543Smrg#if SMI_USE_CAPTURE
13307104f784Smrg	    if (!IS_MSOC(pSmi) && pSmi->Chipset != SMI_COUGAR3DR) {
133109885543Smrg		WRITE_CPR(pSmi, 0x00, READ_CPR(pSmi, 0x00) & ~0x00000001);
133209885543Smrg		WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) & ~0x00F00000);
133309885543Smrg	    }
133409885543Smrg#endif
133509885543Smrg	}
133609885543Smrg        if (pPort->video_memory != NULL) {
133709885543Smrg            SMI_FreeMemory(pScrn, pPort->video_memory);
133809885543Smrg            pPort->video_memory = NULL;
133909885543Smrg	}
134009885543Smrg        pPort->videoStatus = 0;
134109885543Smrg        /* pPort->i2cDevice = 0;aaa*/
134209885543Smrg    } else {
134309885543Smrg        if (pPort->videoStatus & CLIENT_VIDEO_ON) {
134409885543Smrg            pPort->videoStatus |= OFF_TIMER;
134509885543Smrg            pPort->offTime = currentTime.milliseconds + OFF_DELAY;
134609885543Smrg	}
134709885543Smrg    }
134809885543Smrg
13497104f784Smrg    LEAVE();
135009885543Smrg}
135109885543Smrg
135209885543Smrgstatic int
135309885543SmrgSMI_SetPortAttribute(
135409885543Smrg	ScrnInfoPtr	pScrn,
135509885543Smrg	Atom		attribute,
135609885543Smrg	INT32		value,
135709885543Smrg	pointer		data
135809885543Smrg)
135909885543Smrg{
136009885543Smrg    int res;
136109885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
136209885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
136309885543Smrg
13647104f784Smrg    ENTER();
136509885543Smrg
136609885543Smrg    if (attribute == xvColorKey) {
136709885543Smrg	int r, g, b;
136809885543Smrg
136909885543Smrg        pPort->Attribute[XV_COLORKEY] = value;
137009885543Smrg	switch (pScrn->depth) {
137109885543Smrg	case 8:
137209885543Smrg	    SetKeyReg(pSmi, FPR04, value & 0x00FF);
137309885543Smrg	    break;
137409885543Smrg	case 15:
137509885543Smrg	case 16:
137609885543Smrg	    SetKeyReg(pSmi, FPR04, value & 0xFFFF);
137709885543Smrg	    break;
137809885543Smrg	default:
137909885543Smrg	    r = (value & pScrn->mask.red) >> pScrn->offset.red;
138009885543Smrg	    g = (value & pScrn->mask.green) >> pScrn->offset.green;
138109885543Smrg	    b = (value & pScrn->mask.blue) >> pScrn->offset.blue;
138209885543Smrg	    SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3));
138309885543Smrg	    break;
138409885543Smrg	}
138509885543Smrg	res = Success;
138609885543Smrg    } else if (attribute == xvInterlaced) {
138709885543Smrg        pPort->Attribute[XV_INTERLACED] = (value != 0);
138809885543Smrg	res = Success;
138909885543Smrg    } else if (attribute == xvEncoding) {
139009885543Smrg        res = SetAttr(pScrn, XV_ENCODING, value);
139109885543Smrg    } else if (attribute == xvBrightness) {
139209885543Smrg        res = SetAttr(pScrn, XV_BRIGHTNESS, value);
139309885543Smrg    } else if (attribute == xvCapBrightness) {
139409885543Smrg        res = SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, value);
139509885543Smrg    } else if (attribute == xvContrast) {
139609885543Smrg        res = SetAttr(pScrn, XV_CONTRAST, value);
139709885543Smrg    } else if (attribute == xvSaturation) {
139809885543Smrg        res = SetAttr(pScrn, XV_SATURATION, value);
139909885543Smrg    } else if (attribute == xvHue) {
140009885543Smrg        res = SetAttr(pScrn, XV_HUE, value);
140109885543Smrg    } else {
140209885543Smrg        res = BadMatch;
140309885543Smrg    }
140409885543Smrg
14057104f784Smrg    LEAVE(res);
140609885543Smrg}
140709885543Smrg
140809885543Smrg
140909885543Smrgstatic int
141009885543SmrgSMI_GetPortAttribute(
141109885543Smrg	ScrnInfoPtr	pScrn,
141209885543Smrg	Atom		attribute,
141309885543Smrg	INT32		*value,
141409885543Smrg	pointer		data
141509885543Smrg)
141609885543Smrg{
141709885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) data;
141809885543Smrg
14197104f784Smrg    ENTER();
142009885543Smrg    if (attribute == xvEncoding)
142109885543Smrg        *value = pPort->Attribute[XV_ENCODING];
142209885543Smrg    else if (attribute == xvBrightness)
142309885543Smrg        *value = pPort->Attribute[XV_BRIGHTNESS];
142409885543Smrg    else if (attribute == xvCapBrightness)
142509885543Smrg        *value = pPort->Attribute[XV_CAPTURE_BRIGHTNESS];
142609885543Smrg    else if (attribute == xvContrast)
142709885543Smrg        *value = pPort->Attribute[XV_CONTRAST];
142809885543Smrg    else if (attribute == xvSaturation)
142909885543Smrg        *value = pPort->Attribute[XV_SATURATION];
143009885543Smrg    else if (attribute == xvHue)
143109885543Smrg        *value = pPort->Attribute[XV_HUE];
143209885543Smrg    else if (attribute == xvColorKey)
143309885543Smrg        *value = pPort->Attribute[XV_COLORKEY];
14347104f784Smrg    else
14357104f784Smrg	LEAVE(BadMatch);
143609885543Smrg
14377104f784Smrg    LEAVE(Success);
143809885543Smrg}
143909885543Smrg
144009885543Smrg
144109885543Smrgstatic void
144209885543SmrgSMI_QueryBestSize(
144309885543Smrg	ScrnInfoPtr		pScrn,
144409885543Smrg	Bool			motion,
144509885543Smrg	short			vid_w,
144609885543Smrg	short			vid_h,
144709885543Smrg	short			drw_w,
144809885543Smrg	short			drw_h,
144909885543Smrg	unsigned int	*p_w,
145009885543Smrg	unsigned int	*p_h,
145109885543Smrg	pointer			data
145209885543Smrg)
145309885543Smrg{
145409885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
145509885543Smrg
14567104f784Smrg    ENTER();
145709885543Smrg
145809885543Smrg    *p_w = min(drw_w, pSmi->lcdWidth);
145909885543Smrg    *p_h = min(drw_h, pSmi->lcdHeight);
146009885543Smrg
14617104f784Smrg    LEAVE();
146209885543Smrg}
146309885543Smrg
146409885543Smrg
146509885543Smrgstatic int
146609885543SmrgSMI_PutImage(
146709885543Smrg	ScrnInfoPtr		pScrn,
146809885543Smrg	short			src_x,
146909885543Smrg	short			src_y,
147009885543Smrg	short			drw_x,
147109885543Smrg	short			drw_y,
147209885543Smrg	short			src_w,
147309885543Smrg	short			src_h,
147409885543Smrg	short			drw_w,
147509885543Smrg	short			drw_h,
14767104f784Smrg	int			id,
14777104f784Smrg	unsigned char		*buf,
147809885543Smrg	short			width,
147909885543Smrg	short			height,
148009885543Smrg	Bool			sync,
148109885543Smrg	RegionPtr		clipBoxes,
148209885543Smrg	pointer			data,
148309885543Smrg	DrawablePtr		pDraw
148409885543Smrg)
148509885543Smrg{
148609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
148709885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
148809885543Smrg    INT32 x1, y1, x2, y2;
148909885543Smrg    int bpp = 0;
149009885543Smrg    int srcPitch, srcPitch2 = 0, dstPitch, size;
149109885543Smrg    BoxRec dstBox;
149209885543Smrg    CARD32 offset, offset2 = 0, offset3 = 0, tmp;
149309885543Smrg    int left, top, nPixels, nLines;
149409885543Smrg    unsigned char *dstStart;
14957104f784Smrg    xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn);
14967104f784Smrg    xf86CrtcPtr crtc;
149709885543Smrg
14987104f784Smrg    ENTER();
149909885543Smrg
150009885543Smrg    x1 = src_x;
150109885543Smrg    y1 = src_y;
150209885543Smrg    x2 = src_x + src_w;
150309885543Smrg    y2 = src_y + src_h;
150409885543Smrg
150509885543Smrg    dstBox.x1 = drw_x;
150609885543Smrg    dstBox.y1 = drw_y;
150709885543Smrg    dstBox.x2 = drw_x + drw_w;
150809885543Smrg    dstBox.y2 = drw_y + drw_h;
150909885543Smrg
15107104f784Smrg    if (pSmi->CSCVideo) {
15117104f784Smrg	if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
15127104f784Smrg				   width, height))
15137104f784Smrg	    LEAVE(Success);
151409885543Smrg    }
15157104f784Smrg    else {
15167104f784Smrg	if (!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox,
15177104f784Smrg					 &x1, &x2, &y1, &y2, clipBoxes,
15187104f784Smrg					 width, height))
15197104f784Smrg	    LEAVE(Success);
152009885543Smrg
15217b58d2e0Smrg	if (!crtc)
15227b58d2e0Smrg	    LEAVE(Success);
15237b58d2e0Smrg
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
2062b12e5c03SmrgSMI_BlockHandler(BLOCKHANDLER_ARGS_DECL)
206309885543Smrg{
2064b12e5c03Smrg    SCREEN_PTR(arg);
2065b12e5c03Smrg    ScrnInfoPtr	pScrn	= xf86ScreenToScrn(pScreen);
206609885543Smrg    SMIPtr	pSmi    = SMIPTR(pScrn);
206709885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
206809885543Smrg
206909885543Smrg    pScreen->BlockHandler = pSmi->BlockHandler;
2070b12e5c03Smrg    (*pScreen->BlockHandler)(BLOCKHANDLER_ARGS);
207109885543Smrg    pScreen->BlockHandler = SMI_BlockHandler;
207209885543Smrg
207309885543Smrg    if (pPort->videoStatus & TIMER_MASK) {
207409885543Smrg	UpdateCurrentTime();
207509885543Smrg        if (pPort->videoStatus & OFF_TIMER) {
207609885543Smrg            if (pPort->offTime < currentTime.milliseconds) {
207709885543Smrg		if (pSmi->Chipset == SMI_COUGAR3DR) {
207809885543Smrg		    WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE));
207909885543Smrg		}
20807104f784Smrg		else if (IS_MSOC(pSmi))
20817104f784Smrg		    WRITE_DCR(pSmi, 0x0040, READ_DCR(pSmi, 0x0040) & ~0x00000004);
20827104f784Smrg		else
20837104f784Smrg		    WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008);
208409885543Smrg                pPort->videoStatus = FREE_TIMER;
208509885543Smrg                pPort->freeTime = currentTime.milliseconds + FREE_DELAY;
208609885543Smrg	    }
208709885543Smrg	} else {
208809885543Smrg            if (pPort->freeTime < currentTime.milliseconds) {
208909885543Smrg		SMI_FreeMemory(pScrn, pPort->video_memory);
209009885543Smrg                pPort->video_memory = NULL;
209109885543Smrg	    }
209209885543Smrg            pPort->videoStatus = 0;
209309885543Smrg	}
209409885543Smrg    }
209509885543Smrg}
209609885543Smrg
209709885543Smrg#if 0
209809885543Smrgstatic int
209909885543SmrgSMI_SendI2C(
210009885543Smrg	ScrnInfoPtr		pScrn,
210109885543Smrg	CARD8			device,
210209885543Smrg	char			*devName,
210309885543Smrg	SMI_I2CDataPtr	i2cData
210409885543Smrg)
210509885543Smrg{
21067104f784Smrg    SMIPtr	pSmi = SMIPTR(pScrn);
21077104f784Smrg    I2CDevPtr	dev;
21087104f784Smrg    int		status = Success;
210909885543Smrg
21107104f784Smrg    ENTER();
211109885543Smrg
21127104f784Smrg    if (pSmi->I2C == NULL)
21137104f784Smrg	LEAVE(BadAlloc);
211409885543Smrg
21157104f784Smrg    dev = xf86CreateI2CDevRec();
21167104f784Smrg    if (dev == NULL)
21177104f784Smrg	LEAVE(BadAlloc);
211809885543Smrg
21197104f784Smrg    dev->DevName = devName;
21207104f784Smrg    dev->SlaveAddr = device;
21217104f784Smrg    dev->pI2CBus = pSmi->I2C;
21227104f784Smrg
21237104f784Smrg    if (!xf86I2CDevInit(dev))
21247104f784Smrg	status = BadAlloc;
21257104f784Smrg    else {
21267104f784Smrg	while (i2cData->address != 0xFF || i2cData->data != 0xFF) {	/* PDR#676 */
21277104f784Smrg	    if (!xf86I2CWriteByte(dev, i2cData->address, i2cData->data)) {
212809885543Smrg		status = BadAlloc;
21297104f784Smrg		break;
21307104f784Smrg	    }
21317104f784Smrg	    i2cData++;
213209885543Smrg	}
21337104f784Smrg    }
213409885543Smrg
21357104f784Smrg    xf86DestroyI2CDevRec(dev, TRUE);
21367104f784Smrg
21377104f784Smrg    LEAVE(status);
213809885543Smrg}
213909885543Smrg#endif
214009885543Smrg
214109885543Smrg/******************************************************************************\
214209885543Smrg**									      **
214309885543Smrg**	 O F F S C R E E N   M E M O R Y   M A N A G E R		      **
214409885543Smrg**									      **
214509885543Smrg\******************************************************************************/
214609885543Smrg
214709885543Smrgstatic void
214809885543SmrgSMI_InitOffscreenImages(
214909885543Smrg	ScreenPtr	pScreen
215009885543Smrg)
215109885543Smrg{
215209885543Smrg    XF86OffscreenImagePtr offscreenImages;
2153b12e5c03Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
215409885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
215509885543Smrg    SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr;
215609885543Smrg
21577104f784Smrg    ENTER();
215809885543Smrg
21597b58d2e0Smrg    offscreenImages = malloc(sizeof(XF86OffscreenImageRec));
216009885543Smrg    if (offscreenImages == NULL) {
21617104f784Smrg	LEAVE();
216209885543Smrg    }
216309885543Smrg
216409885543Smrg    offscreenImages->image = SMI_VideoImages;
21657104f784Smrg    offscreenImages->flags = VIDEO_OVERLAID_IMAGES;
21667104f784Smrg    if (IS_MSOC(pSmi))
21677104f784Smrg	offscreenImages->flags |= VIDEO_CLIP_TO_VIEWPORT;
216809885543Smrg    offscreenImages->alloc_surface = SMI_AllocSurface;
216909885543Smrg    offscreenImages->free_surface = SMI_FreeSurface;
217009885543Smrg    offscreenImages->display = SMI_DisplaySurface;
217109885543Smrg    offscreenImages->stop = SMI_StopSurface;
217209885543Smrg    offscreenImages->getAttribute = SMI_GetSurfaceAttribute;
217309885543Smrg    offscreenImages->setAttribute = SMI_SetSurfaceAttribute;
217409885543Smrg    offscreenImages->max_width = pSmi->lcdWidth;
217509885543Smrg    offscreenImages->max_height = pSmi->lcdHeight;
217609885543Smrg    if (!pPort->I2CDev.SlaveAddr) {
217709885543Smrg	offscreenImages->num_attributes = nElems(SMI_VideoAttributes);
217809885543Smrg	offscreenImages->attributes = SMI_VideoAttributes;
217909885543Smrg    } else {
218009885543Smrg	offscreenImages->num_attributes = nElems(SMI_VideoAttributesSAA711x);
218109885543Smrg	offscreenImages->attributes = SMI_VideoAttributesSAA711x;
218209885543Smrg    }
218309885543Smrg    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
218409885543Smrg
21857104f784Smrg    LEAVE();
218609885543Smrg}
218709885543Smrg
218809885543Smrgstatic void
218909885543SmrgSMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area)
219009885543Smrg{
2191b12e5c03Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
219209885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
219309885543Smrg    SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr;
219409885543Smrg
21957104f784Smrg    ENTER();
219609885543Smrg
219709885543Smrg    if (pPort->video_memory == area)
219809885543Smrg	pPort->video_memory = NULL;
219909885543Smrg
22007104f784Smrg    LEAVE();
220109885543Smrg}
220209885543Smrg
22037104f784SmrgCARD32
22047104f784SmrgSMI_AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size)
220509885543Smrg{
2206b12e5c03Smrg    ScreenPtr	pScreen = xf86ScrnToScreen(pScrn);
22077104f784Smrg    SMIPtr	pSmi = SMIPTR(pScrn);
22087104f784Smrg    int		offset = 0;
220909885543Smrg
22107104f784Smrg    ENTER();
221109885543Smrg
221209885543Smrg    if (pSmi->useEXA) {
221309885543Smrg	ExaOffscreenArea *area = *mem_struct;
221409885543Smrg
221509885543Smrg	if (area != NULL) {
221609885543Smrg	    if (area->size >= size)
22177104f784Smrg		LEAVE(area->offset);
221809885543Smrg
221909885543Smrg	    exaOffscreenFree(pScrn->pScreen, area);
222009885543Smrg	}
222109885543Smrg
22227104f784Smrg	area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE,
22237104f784Smrg				 SMI_VideoSave, NULL);
222409885543Smrg
222509885543Smrg	*mem_struct = area;
22267104f784Smrg	if (area != NULL)
22277104f784Smrg	    offset = area->offset;
22287104f784Smrg    }
22297104f784Smrg    else {
22307104f784Smrg	FBLinearPtr	linear = *mem_struct;
223109885543Smrg
223209885543Smrg	/*  XAA allocates in units of pixels at the screen bpp,
223309885543Smrg	 *  so adjust size appropriately.
223409885543Smrg	 */
223509885543Smrg	size = (size + pSmi->Bpp - 1) / pSmi->Bpp;
223609885543Smrg
223709885543Smrg	if (linear) {
223809885543Smrg	    if (linear->size >= size)
22397104f784Smrg		LEAVE(linear->offset * pSmi->Bpp);
224009885543Smrg
224109885543Smrg	    if (xf86ResizeOffscreenLinear(linear, size))
22427104f784Smrg		LEAVE(linear->offset * pSmi->Bpp);
224309885543Smrg
22447104f784Smrg	    xf86FreeOffscreenLinear(linear);
22457104f784Smrg	}
22467104f784Smrg	else {
22477104f784Smrg	    int max_size;
224809885543Smrg
22497104f784Smrg	    xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16,
22507104f784Smrg					    PRIORITY_EXTREME);
22517104f784Smrg	    if (max_size < size)
22527104f784Smrg		LEAVE(0);
225309885543Smrg
22547104f784Smrg	    xf86PurgeUnlockedOffscreenAreas(pScreen);
225509885543Smrg	}
225609885543Smrg
22577104f784Smrg	linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
22587104f784Smrg					     NULL, NULL, NULL);
22597104f784Smrg	if ((*mem_struct = linear) != NULL)
22607104f784Smrg	    offset = linear->offset * pSmi->Bpp;
22617104f784Smrg
22627104f784Smrg	DEBUG("offset = %p\n", offset);
226309885543Smrg    }
226409885543Smrg
22657104f784Smrg    LEAVE(offset);
226609885543Smrg}
226709885543Smrg
22687104f784Smrgvoid
226909885543SmrgSMI_FreeMemory(
227009885543Smrg	ScrnInfoPtr pScrn,
227109885543Smrg	void *mem_struct
227209885543Smrg)
227309885543Smrg{
227409885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
227509885543Smrg
22767104f784Smrg    ENTER();
227709885543Smrg
227809885543Smrg    if (pSmi->useEXA) {
227909885543Smrg	ExaOffscreenArea *area = mem_struct;
228009885543Smrg
228109885543Smrg	if (area != NULL)
228209885543Smrg	    exaOffscreenFree(pScrn->pScreen, area);
228309885543Smrg    } else {
228409885543Smrg	FBLinearPtr linear = mem_struct;
228509885543Smrg
228609885543Smrg	if (linear != NULL)
228709885543Smrg	    xf86FreeOffscreenLinear(linear);
228809885543Smrg    }
228909885543Smrg
22907104f784Smrg    LEAVE();
22917104f784Smrg}
22927104f784Smrg
22937104f784Smrgstatic void
22947104f784SmrgCopyYV12ToVideoMem(unsigned char *src1, unsigned char *src2,
22957104f784Smrg		   unsigned char *src3, unsigned char *dst,
22967104f784Smrg		   int src1Pitch, int src23Pitch, int dstPitch,
22977104f784Smrg		   int height, int width)
22987104f784Smrg{
22997104f784Smrg    int		j = height;
23007104f784Smrg
23017104f784Smrg    ENTER();
23027104f784Smrg
23037104f784Smrg    /* copy 1 data */
23047104f784Smrg    while (j -- > 0) {
23057104f784Smrg	memcpy(dst, src1, width);
23067104f784Smrg	src1 += src1Pitch;
23077104f784Smrg	dst += dstPitch;
23087104f784Smrg    }
23097104f784Smrg    /* copy 2 data */
23107104f784Smrg    j = height / 2;
23117104f784Smrg    while (j -- > 0) {
23127104f784Smrg	memcpy(dst, src2, width / 2);
23137104f784Smrg	src2 += src23Pitch;
23147104f784Smrg	dst += dstPitch / 2;
23157104f784Smrg    }
23167104f784Smrg    /* copy 3 data */
23177104f784Smrg    j = height / 2;
23187104f784Smrg    while (j -- > 0) {
23197104f784Smrg	memcpy(dst, src3, width / 2);
23207104f784Smrg	src3 += src23Pitch;
23217104f784Smrg	dst += dstPitch / 2;
23227104f784Smrg    }
23237104f784Smrg
23247104f784Smrg    LEAVE();
232509885543Smrg}
232609885543Smrg
232709885543Smrgstatic int
232809885543SmrgSMI_AllocSurface(
232909885543Smrg	ScrnInfoPtr	pScrn,
233009885543Smrg	int		id,
233109885543Smrg	unsigned short	width,
233209885543Smrg	unsigned short	height,
233309885543Smrg	XF86SurfacePtr	surface
233409885543Smrg)
233509885543Smrg{
233609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
233709885543Smrg    int pitch, bpp, offset, size;
233809885543Smrg    void *surface_memory = NULL;
233909885543Smrg    SMI_OffscreenPtr ptrOffscreen;
234009885543Smrg
23417104f784Smrg    ENTER();
234209885543Smrg
23437104f784Smrg    if (width > pSmi->lcdWidth || height > pSmi->lcdHeight)
23447104f784Smrg	LEAVE(BadAlloc);
234509885543Smrg
234609885543Smrg    switch (id) {
234709885543Smrg    case FOURCC_YV12:
234809885543Smrg    case FOURCC_I420:
234909885543Smrg    case FOURCC_YUY2:
235009885543Smrg    case FOURCC_RV15:
235109885543Smrg    case FOURCC_RV16:
235209885543Smrg	bpp = 2;
235309885543Smrg	break;
235409885543Smrg    case FOURCC_RV24:
235509885543Smrg	bpp = 3;
235609885543Smrg	break;
235709885543Smrg    case FOURCC_RV32:
235809885543Smrg	bpp = 4;
235909885543Smrg	break;
236009885543Smrg    default:
23617104f784Smrg	LEAVE(BadAlloc);
236209885543Smrg    }
236309885543Smrg
236409885543Smrg    width = (width + 1) & ~1;
236509885543Smrg    pitch = (width * bpp + 15) & ~15;
236609885543Smrg    size  = pitch * height;
236709885543Smrg
236809885543Smrg    offset = SMI_AllocateMemory(pScrn, &surface_memory, size);
23697104f784Smrg    if (offset == 0)
23707104f784Smrg	LEAVE(BadAlloc);
237109885543Smrg
23727b58d2e0Smrg    surface->pitches = malloc(sizeof(int));
237309885543Smrg    if (surface->pitches == NULL) {
237409885543Smrg	SMI_FreeMemory(pScrn, surface_memory);
23757104f784Smrg	LEAVE(BadAlloc);
237609885543Smrg    }
23777b58d2e0Smrg    surface->offsets = malloc(sizeof(int));
237809885543Smrg    if (surface->offsets == NULL) {
23797b58d2e0Smrg	free(surface->pitches);
238009885543Smrg	SMI_FreeMemory(pScrn, surface_memory);
23817104f784Smrg	LEAVE(BadAlloc);
238209885543Smrg    }
238309885543Smrg
23847b58d2e0Smrg    ptrOffscreen = malloc(sizeof(SMI_OffscreenRec));
238509885543Smrg    if (ptrOffscreen == NULL) {
23867b58d2e0Smrg	free(surface->offsets);
23877b58d2e0Smrg	free(surface->pitches);
238809885543Smrg	SMI_FreeMemory(pScrn, surface_memory);
23897104f784Smrg	LEAVE(BadAlloc);
239009885543Smrg    }
239109885543Smrg
239209885543Smrg    surface->pScrn = pScrn;
239309885543Smrg    surface->id = id;
239409885543Smrg    surface->width = width;
239509885543Smrg    surface->height = height;
239609885543Smrg    surface->pitches[0] = pitch;
239709885543Smrg    surface->offsets[0] = offset;
239809885543Smrg    surface->devPrivate.ptr = (pointer) ptrOffscreen;
239909885543Smrg
240009885543Smrg    ptrOffscreen->surface_memory = surface_memory;
240109885543Smrg    ptrOffscreen->isOn = FALSE;
240209885543Smrg
24037104f784Smrg    LEAVE(Success);
240409885543Smrg}
240509885543Smrg
240609885543Smrgstatic int
240709885543SmrgSMI_FreeSurface(
240809885543Smrg	XF86SurfacePtr	surface
240909885543Smrg)
241009885543Smrg{
241109885543Smrg    ScrnInfoPtr pScrn = surface->pScrn;
241209885543Smrg    SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr;
241309885543Smrg
24147104f784Smrg    ENTER();
241509885543Smrg
241609885543Smrg    if (ptrOffscreen->isOn) {
241709885543Smrg	SMI_StopSurface(surface);
241809885543Smrg    }
241909885543Smrg
242009885543Smrg    SMI_FreeMemory(pScrn, ptrOffscreen->surface_memory);
24217b58d2e0Smrg    free(surface->pitches);
24227b58d2e0Smrg    free(surface->offsets);
24237b58d2e0Smrg    free(surface->devPrivate.ptr);
242409885543Smrg
24257104f784Smrg    LEAVE(Success);
242609885543Smrg}
242709885543Smrg
242809885543Smrgstatic int
242909885543SmrgSMI_DisplaySurface(
243009885543Smrg	XF86SurfacePtr	surface,
243109885543Smrg	short		vid_x,
243209885543Smrg	short		vid_y,
243309885543Smrg	short		drw_x,
243409885543Smrg	short		drw_y,
243509885543Smrg	short		vid_w,
243609885543Smrg	short		vid_h,
243709885543Smrg	short		drw_w,
243809885543Smrg	short		drw_h,
243909885543Smrg	RegionPtr	clipBoxes
244009885543Smrg)
244109885543Smrg{
244209885543Smrg    SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr;
244309885543Smrg    SMIPtr pSmi = SMIPTR(surface->pScrn);
244409885543Smrg    SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr;
244509885543Smrg    INT32 x1, y1, x2, y2;
244609885543Smrg    BoxRec dstBox;
24477104f784Smrg    xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(surface->pScrn);
24487104f784Smrg    xf86CrtcPtr crtc;
244909885543Smrg
24507104f784Smrg    ENTER();
245109885543Smrg
245209885543Smrg    x1 = vid_x;
245309885543Smrg    x2 = vid_x + vid_w;
245409885543Smrg    y1 = vid_y;
245509885543Smrg    y2 = vid_y + vid_h;
245609885543Smrg
245709885543Smrg    dstBox.x1 = drw_x;
245809885543Smrg    dstBox.x2 = drw_x + drw_w;
245909885543Smrg    dstBox.y1 = drw_y;
246009885543Smrg    dstBox.y2 = drw_y + drw_h;
246109885543Smrg
24627104f784Smrg    if(!xf86_crtc_clip_video_helper(surface->pScrn, &crtc, crtcConf->crtc[0], &dstBox,
24637104f784Smrg				    &x1, &x2, &y1, &y2, clipBoxes, surface->width, surface->height))
24647104f784Smrg	LEAVE(Success);
246509885543Smrg
24667b58d2e0Smrg    if (!crtc)
24677b58d2e0Smrg	LEAVE(Success);
24687b58d2e0Smrg
24697104f784Smrg    /* Transform dstBox to the CRTC coordinates */
24707104f784Smrg    dstBox.x1 -= crtc->x;
24717104f784Smrg    dstBox.y1 -= crtc->y;
24727104f784Smrg    dstBox.x2 -= crtc->x;
24737104f784Smrg    dstBox.y2 -= crtc->y;
247409885543Smrg
247509885543Smrg    xf86XVFillKeyHelper(surface->pScrn->pScreen,
247609885543Smrg			pPort->Attribute[XV_COLORKEY], clipBoxes);
24777104f784Smrg    SMI_ResetVideo(surface->pScrn);
247809885543Smrg
24797104f784Smrg    if (pSmi->Chipset == SMI_COUGAR3DR)
248009885543Smrg	SMI_DisplayVideo0730(surface->pScrn, surface->id, surface->offsets[0],
248109885543Smrg			     surface->width, surface->height, surface->pitches[0], x1, y1, x2,
248209885543Smrg			     y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
24837104f784Smrg    else if (IS_MSOC(pSmi))
24847104f784Smrg	SMI_DisplayVideo0501(surface->pScrn, surface->id,
24857104f784Smrg			     surface->offsets[0], surface->width,
24867104f784Smrg			     surface->height, surface->pitches[0], x1, y1,
24877104f784Smrg			     x2, y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
24887104f784Smrg    else{
24897104f784Smrg	if(crtc == crtcConf->crtc[0])
24907104f784Smrg	    SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0],
24917104f784Smrg			     surface->width, surface->height, surface->pitches[0], x1, y1, x2,
24927104f784Smrg			     y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
249309885543Smrg    }
249409885543Smrg
249509885543Smrg    ptrOffscreen->isOn = TRUE;
249609885543Smrg    if (pPort->videoStatus & CLIENT_VIDEO_ON) {
249709885543Smrg        REGION_EMPTY(surface->pScrn->pScreen, &pPort->clip);
249809885543Smrg	UpdateCurrentTime();
249909885543Smrg        pPort->videoStatus = FREE_TIMER;
250009885543Smrg        pPort->freeTime = currentTime.milliseconds + FREE_DELAY;
250109885543Smrg    }
250209885543Smrg
25037104f784Smrg    LEAVE(Success);
250409885543Smrg}
250509885543Smrg
250609885543Smrgstatic int
250709885543SmrgSMI_StopSurface(
250809885543Smrg	XF86SurfacePtr	surface
250909885543Smrg)
251009885543Smrg{
251109885543Smrg    SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr;
251209885543Smrg
25137104f784Smrg    ENTER();
251409885543Smrg
251509885543Smrg    if (ptrOffscreen->isOn) {
251609885543Smrg	SMIPtr pSmi = SMIPTR(surface->pScrn);
251709885543Smrg	if (pSmi->Chipset == SMI_COUGAR3DR) {
251809885543Smrg	    WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE));
251909885543Smrg	} else {
252009885543Smrg	    WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008);
252109885543Smrg	}
252209885543Smrg
252309885543Smrg	ptrOffscreen->isOn = FALSE;
252409885543Smrg    }
252509885543Smrg
25267104f784Smrg    LEAVE(Success);
252709885543Smrg}
252809885543Smrg
252909885543Smrgstatic int
253009885543SmrgSMI_GetSurfaceAttribute(
253109885543Smrg	ScrnInfoPtr	pScrn,
253209885543Smrg	Atom		attr,
253309885543Smrg	INT32		*value
253409885543Smrg)
253509885543Smrg{
253609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
253709885543Smrg
253809885543Smrg    return SMI_GetPortAttribute(pScrn, attr, value,
253909885543Smrg			(pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr);
254009885543Smrg}
254109885543Smrg
254209885543Smrgstatic int
254309885543SmrgSMI_SetSurfaceAttribute(
254409885543Smrg	ScrnInfoPtr	pScrn,
254509885543Smrg	Atom		attr,
254609885543Smrg	INT32		value
254709885543Smrg)
254809885543Smrg{
254909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
255009885543Smrg
255109885543Smrg    return SMI_SetPortAttribute(pScrn, attr, value,
255209885543Smrg			(pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr);
255309885543Smrg}
255409885543Smrg
255509885543Smrgstatic void
255609885543SmrgSetKeyReg(SMIPtr pSmi, int reg, int value)
255709885543Smrg{
25587104f784Smrg    if (pSmi->Chipset == SMI_COUGAR3DR)
255909885543Smrg	WRITE_FPR(pSmi, reg, value);
25607104f784Smrg    else if (IS_MSOC(pSmi)) {
25617104f784Smrg	/* We don't change the color mask, and we don't do brightness.  IF
25627104f784Smrg	 * they write to the colorkey register, we'll write the value to the
25637104f784Smrg	 * 501 colorkey register */
25647104f784Smrg	if (FPR04 == reg)		   /* Only act on colorkey value writes */
25657104f784Smrg	    WRITE_DCR(pSmi, 0x0008, value);/* ColorKey register is DCR08 */
256609885543Smrg    }
25677104f784Smrg    else
25687104f784Smrg	WRITE_VPR(pSmi, reg, value);
256909885543Smrg}
257009885543Smrg
257109885543Smrg#else /* SMI_USE_VIDEO */
257209885543Smrgvoid SMI_InitVideo(ScreenPtr pScreen) {}
257309885543Smrg#endif
2574