smi_video.c revision 09885543
109885543Smrg/* Header: //Mercury/Projects/archives/XFree86/4.0/smi_video.c.-arc 1.14 30 Nov 2000 16:51:40 Frido $ */ 209885543Smrg/* 309885543SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 409885543SmrgCopyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 509885543SmrgCopyright (C) 2001 Corvin Zahn. 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 3009885543Smrg/* 3109885543Smrgthis is a heavy modified version of the V1.2.2 original siliconmotion driver. 3209885543Smrg- SAA7111 support 3309885543Smrg- supports attributes: XV_ENCODING, XV_BRIGHTNESS, XV_CONTRAST, 3409885543Smrg XV_SATURATION, XV_HUE, XV_COLORKEY, XV_INTERLACED 3509885543Smrg XV_CAPTURE_BRIGHTNESS can be used to set brightness in the capture device 3609885543Smrg- bug fixes 3709885543Smrg- tries not to use acceleration functions 3809885543Smrg- interlaced video for double vertical resolution 3909885543Smrg 4009885543SmrgAuthor of changes: Corvin Zahn <zahn@zac.de> 4109885543SmrgDate: 2.11.2001 4209885543Smrg*/ 4309885543Smrg 4409885543Smrg/* $XdotOrg: driver/xf86-video-siliconmotion/src/smi_video.c,v 1.5 2005/07/11 02:29:59 ajax Exp $ */ 4509885543Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c,v 1.13 2003/11/10 18:22:26 tsi Exp $ */ 4609885543Smrg 4709885543Smrg#ifdef HAVE_CONFIG_H 4809885543Smrg#include "config.h" 4909885543Smrg#endif 5009885543Smrg 5109885543Smrg#include "smi.h" 5209885543Smrg#include "smi_video.h" 5309885543Smrg 5409885543Smrg 5509885543Smrg/* 5609885543Smrg 5709885543Smrgnew attribute: 5809885543Smrg 5909885543SmrgXV_INTERLACED = 0: only one field of an interlaced video signal is displayed: 6009885543Smrg -> half vertical resolution, but no comb like artifacts from 6109885543Smrg moving vertical edges 6209885543SmrgXV_INTERLACED = 1: both fields of an interlaced video signal are displayed: 6309885543Smrg -> full vertical resolution, but comb like artifacts from 6409885543Smrg moving vertical edges 6509885543Smrg 6609885543SmrgThe default value can be set with the driver option Interlaced 6709885543Smrg 6809885543Smrg*/ 6909885543Smrg 7009885543Smrg 7109885543Smrg 7209885543Smrg 7309885543Smrg#undef MIN 7409885543Smrg#undef ABS 7509885543Smrg#undef CLAMP 7609885543Smrg#undef ENTRIES 7709885543Smrg 7809885543Smrg#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 7909885543Smrg#define ABS(n) (((n) < 0) ? -(n) : (n)) 8009885543Smrg#define CLAMP(v, min, max) (((v) < (min)) ? (min) : MIN(v, max)) 8109885543Smrg 8209885543Smrg#define ENTRIES(array) (sizeof(array) / sizeof((array)[0])) 8309885543Smrg#define nElems(x) (sizeof(x) / sizeof(x[0])) 8409885543Smrg 8509885543Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 8609885543Smrg 8709885543Smrg#if SMI_USE_VIDEO 8809885543Smrg#include "dixstruct.h" 8909885543Smrg 9009885543Smrg 9109885543Smrgstatic int SMI_AddEncoding(XF86VideoEncodingPtr enc, int i, 9209885543Smrg int norm, int input, int channel); 9309885543Smrgstatic void SMI_BuildEncodings(SMI_PortPtr p); 9409885543Smrg 9509885543Smrgstatic XF86VideoAdaptorPtr SMI_SetupVideo(ScreenPtr pScreen); 9609885543Smrgstatic void SMI_ResetVideo(ScrnInfoPtr pScrn); 9709885543Smrg 9809885543Smrg#if SMI_USE_CAPTURE 9909885543Smrgstatic int SMI_PutVideo(ScrnInfoPtr pScrn, 10009885543Smrg short vid_x, short vid_y, short drw_x, short drw_y, 10109885543Smrg short vid_w, short vid_h, short drw_w, short drw_h, 10209885543Smrg RegionPtr clipBoxes, pointer data, DrawablePtr); 10309885543Smrg#endif 10409885543Smrgstatic void SMI_StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown); 10509885543Smrgstatic int SMI_SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, 10609885543Smrg INT32 value, pointer data); 10709885543Smrgstatic int SMI_GetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, 10809885543Smrg INT32 *value, pointer data); 10909885543Smrgstatic void SMI_QueryBestSize(ScrnInfoPtr pScrn, Bool motion, 11009885543Smrg short vid_w, short vid_h, short drw_w, short drw_h, 11109885543Smrg unsigned int *p_w, unsigned int *p_h, pointer data); 11209885543Smrgstatic int SMI_PutImage(ScrnInfoPtr pScrn, 11309885543Smrg short src_x, short src_y, short drw_x, short drw_y, 11409885543Smrg short src_w, short src_h, short drw_w, short drw_h, 11509885543Smrg int id, unsigned char *buf, short width, short height, Bool sync, 11609885543Smrg RegionPtr clipBoxes, pointer data, DrawablePtr); 11709885543Smrgstatic int SMI_QueryImageAttributes(ScrnInfoPtr pScrn, 11809885543Smrg int id, unsigned short *width, unsigned short *height, 11909885543Smrg int *picthes, int *offsets); 12009885543Smrg 12109885543Smrgstatic Bool SMI_ClipVideo(ScrnInfoPtr pScrn, BoxPtr dst, 12209885543Smrg INT32 *x1, INT32 *y1, INT32 *x2, INT32 *y2, 12309885543Smrg RegionPtr reg, INT32 width, INT32 height); 12409885543Smrgstatic void SMI_DisplayVideo(ScrnInfoPtr pScrn, int id, int offset, 12509885543Smrg short width, short height, int pitch, int x1, int y1, int x2, int y2, 12609885543Smrg BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h); 12709885543Smrgstatic void SMI_DisplayVideo0730(ScrnInfoPtr pScrn, int id, int offset, 12809885543Smrg short width, short height, int pitch, int x1, int y1, int x2, int y2, 12909885543Smrg BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h); 13009885543Smrgstatic void SMI_BlockHandler(int i, pointer blockData, pointer pTimeout, 13109885543Smrg pointer pReadMask); 13209885543Smrg#if 0 13309885543Smrgstatic void SMI_WaitForSync(ScrnInfoPtr pScrn); 13409885543Smrg#endif 13509885543Smrg/*static int SMI_SendI2C(ScrnInfoPtr pScrn, CARD8 device, char *devName, 13609885543Smrg SMI_I2CDataPtr i2cData);*/ 13709885543Smrg 13809885543Smrgstatic void SMI_InitOffscreenImages(ScreenPtr pScreen); 13909885543Smrgstatic void SMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area); 14009885543Smrgstatic CARD32 SMI_AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size); 14109885543Smrgstatic void SMI_FreeMemory(ScrnInfoPtr pScrn, void *mem_struct); 14209885543Smrg 14309885543Smrg 14409885543Smrgstatic int SMI_AllocSurface(ScrnInfoPtr pScrn, 14509885543Smrg int id, unsigned short width, unsigned short height, 14609885543Smrg XF86SurfacePtr surface); 14709885543Smrgstatic int SMI_FreeSurface(XF86SurfacePtr surface); 14809885543Smrgstatic int SMI_DisplaySurface(XF86SurfacePtr surface, 14909885543Smrg short vid_x, short vid_y, short drw_x, short drw_y, 15009885543Smrg short vid_w, short vid_h, short drw_w, short drw_h, 15109885543Smrg RegionPtr clipBoxes); 15209885543Smrgstatic int SMI_StopSurface(XF86SurfacePtr surface); 15309885543Smrgstatic int SMI_GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 *value); 15409885543Smrgstatic int SMI_SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 value); 15509885543Smrg 15609885543Smrgstatic int SetAttr(ScrnInfoPtr pScrn, int i, int value); 15709885543Smrgstatic int SetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value); 15809885543Smrgstatic int SetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value); 15909885543Smrgstatic void SetKeyReg(SMIPtr pSmi, int reg, int value); 16009885543Smrg 16109885543Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) 16209885543Smrgstatic Bool RegionsEqual(RegionPtr A, RegionPtr B); 16309885543Smrg#endif 16409885543Smrg/** 16509885543Smrg * Atoms 16609885543Smrg */ 16709885543Smrg 16809885543Smrgstatic Atom xvColorKey; 16909885543Smrgstatic Atom xvEncoding; 17009885543Smrgstatic Atom xvBrightness,xvCapBrightness, xvContrast, xvSaturation, xvHue; 17109885543Smrgstatic Atom xvInterlaced; 17209885543Smrg 17309885543Smrg 17409885543Smrg/******************************************************************************\ 17509885543Smrg** ** 17609885543Smrg** C A P A B I L I T I E S ** 17709885543Smrg** ** 17809885543Smrg\******************************************************************************/ 17909885543Smrg 18009885543Smrg 18109885543Smrg/**************************************************************************/ 18209885543Smrg/* input channels */ 18309885543Smrg 18409885543Smrg#define N_COMPOSITE_CHANNELS 4 18509885543Smrg#define N_SVIDEO_CHANNELS 2 18609885543Smrg 18709885543Smrg#define N_VIDEO_INPUTS 2 18809885543Smrgtypedef enum _VideoInput { VID_COMPOSITE, VID_SVIDEO } VideoInput; 18909885543Smrg 19009885543Smrg 19109885543Smrg/**************************************************************************/ 19209885543Smrg/* video input formats */ 19309885543Smrg 19409885543Smrgtypedef struct _VideoInputDataRec { 19509885543Smrg char* name; 19609885543Smrg} VideoInputDataRec; 19709885543Smrg 19809885543Smrgstatic VideoInputDataRec VideoInputs[] = { 19909885543Smrg { "composite" }, 20009885543Smrg { "svideo" } 20109885543Smrg}; 20209885543Smrg 20309885543Smrg 20409885543Smrg/**************************************************************************/ 20509885543Smrg/* video norms */ 20609885543Smrg 20709885543Smrg#define N_VIDEO_NORMS 3 20809885543Smrgtypedef enum _VideoNorm { PAL, NTSC, SECAM } VideoNorm; 20909885543Smrg 21009885543Smrgtypedef struct _VideoNormDataRec { 21109885543Smrg char* name; 21209885543Smrg unsigned long Wt; 21309885543Smrg unsigned long Wa; 21409885543Smrg unsigned long Ht; 21509885543Smrg unsigned long Ha; 21609885543Smrg unsigned long HStart; 21709885543Smrg unsigned long VStart; 21809885543Smrg XvRationalRec rate; 21909885543Smrg} VideoNormDataRec; 22009885543Smrg 22109885543Smrg 22209885543Smrgstatic VideoNormDataRec VideoNorms[] = 22309885543Smrg{ 22409885543Smrg /* PAL-BDGHI */ 22509885543Smrg {"pal", 864, 704, 625, 576, 16, 16, { 1, 50 }}, 22609885543Smrg /* NTSC */ 22709885543Smrg {"ntsc", 858, 704, 525, 480, 21, 8, { 1001, 60000 }}, 22809885543Smrg /* SECAM (not tested) */ 22909885543Smrg {"secam", 864, 7040, 625, 576, 31, 16, { 1, 50 }}, 23009885543Smrg}; 23109885543Smrg 23209885543Smrg 23309885543Smrg/**************************************************************************/ 23409885543Smrg/* number of (generated) XV_ENCODING vaulues */ 23509885543Smrg#define N_ENCODINGS ((N_VIDEO_NORMS) * (N_COMPOSITE_CHANNELS + N_SVIDEO_CHANNELS)) 23609885543Smrg 23709885543Smrg 23809885543Smrg/**************************************************************************/ 23909885543Smrg 24009885543Smrgstatic XF86VideoFormatRec SMI_VideoFormats[] = 24109885543Smrg{ 24209885543Smrg { 15, TrueColor }, /* depth, class */ 24309885543Smrg { 16, TrueColor }, /* depth, class */ 24409885543Smrg { 24, TrueColor }, /* depth, class */ 24509885543Smrg}; 24609885543Smrg 24709885543Smrg 24809885543Smrg/**************************************************************************/ 24909885543Smrg 25009885543Smrg/** 25109885543Smrg * Attributes 25209885543Smrg */ 25309885543Smrg 25409885543Smrg#define XV_ENCODING_NAME "XV_ENCODING" 25509885543Smrg#define XV_BRIGHTNESS_NAME "XV_BRIGHTNESS" 25609885543Smrg#define XV_CAPTURE_BRIGHTNESS_NAME "XV_CAPTURE_BRIGHTNESS" 25709885543Smrg#define XV_CONTRAST_NAME "XV_CONTRAST" 25809885543Smrg#define XV_SATURATION_NAME "XV_SATURATION" 25909885543Smrg#define XV_HUE_NAME "XV_HUE" 26009885543Smrg#define XV_COLORKEY_NAME "XV_COLORKEY" 26109885543Smrg#define XV_INTERLACED_NAME "XV_INTERLACED" 26209885543Smrg 26309885543Smrg 26409885543Smrg/* fixed order! */ 26509885543Smrgstatic XF86AttributeRec SMI_VideoAttributesSAA711x[N_ATTRS] = { 26609885543Smrg {XvSettable | XvGettable, 0, N_ENCODINGS-1, XV_ENCODING_NAME}, 26709885543Smrg {XvSettable | XvGettable, 0, 255, XV_BRIGHTNESS_NAME}, 26809885543Smrg {XvSettable | XvGettable, 0, 255, XV_CAPTURE_BRIGHTNESS_NAME}, 26909885543Smrg {XvSettable | XvGettable, 0, 127, XV_CONTRAST_NAME}, 27009885543Smrg {XvSettable | XvGettable, 0, 127, XV_SATURATION_NAME}, 27109885543Smrg {XvSettable | XvGettable, -128, 127, XV_HUE_NAME}, 27209885543Smrg {XvSettable | XvGettable, 0x000000, 0xFFFFFF, XV_COLORKEY_NAME}, 27309885543Smrg {XvSettable | XvGettable, 0, 1, XV_INTERLACED_NAME}, 27409885543Smrg}; 27509885543Smrg 27609885543Smrgstatic XF86AttributeRec SMI_VideoAttributes[2] = { 27709885543Smrg {XvSettable | XvGettable, 0, 255, XV_BRIGHTNESS_NAME}, 27809885543Smrg {XvSettable | XvGettable, 0x000000, 0xFFFFFF, XV_COLORKEY_NAME}, 27909885543Smrg}; 28009885543Smrg 28109885543Smrg 28209885543Smrg/**************************************************************************/ 28309885543Smrgstatic XF86ImageRec SMI_VideoImages[] = 28409885543Smrg{ 28509885543Smrg XVIMAGE_YUY2, 28609885543Smrg XVIMAGE_YV12, 28709885543Smrg XVIMAGE_I420, 28809885543Smrg { 28909885543Smrg FOURCC_RV15, /* id */ 29009885543Smrg XvRGB, /* type */ 29109885543Smrg LSBFirst, /* byte_order */ 29209885543Smrg { 'R', 'V' ,'1', '5', 29309885543Smrg 0x00, '5', 0x00, 0x00, 29409885543Smrg 0x00, 0x00, 0x00, 0x00, 29509885543Smrg 0x00, 0x00, 0x00, 0x00 }, /* guid */ 29609885543Smrg 16, /* bits_per_pixel */ 29709885543Smrg XvPacked, /* format */ 29809885543Smrg 1, /* num_planes */ 29909885543Smrg 15, /* depth */ 30009885543Smrg 0x001F, 0x03E0, 0x7C00, /* red_mask, green, blue */ 30109885543Smrg 0, 0, 0, /* y_sample_bits, u, v */ 30209885543Smrg 0, 0, 0, /* horz_y_period, u, v */ 30309885543Smrg 0, 0, 0, /* vert_y_period, u, v */ 30409885543Smrg { 'R', 'V', 'B' }, /* component_order */ 30509885543Smrg XvTopToBottom /* scaline_order */ 30609885543Smrg }, 30709885543Smrg { 30809885543Smrg FOURCC_RV16, /* id */ 30909885543Smrg XvRGB, /* type */ 31009885543Smrg LSBFirst, /* byte_order */ 31109885543Smrg { 'R', 'V' ,'1', '6', 31209885543Smrg 0x00, 0x00, 0x00, 0x00, 31309885543Smrg 0x00, 0x00, 0x00, 0x00, 31409885543Smrg 0x00, 0x00, 0x00, 0x00 }, /* guid */ 31509885543Smrg 16, /* bits_per_pixel */ 31609885543Smrg XvPacked, /* format */ 31709885543Smrg 1, /* num_planes */ 31809885543Smrg 16, /* depth */ 31909885543Smrg 0x001F, 0x07E0, 0xF800, /* red_mask, green, blue */ 32009885543Smrg 0, 0, 0, /* y_sample_bits, u, v */ 32109885543Smrg 0, 0, 0, /* horz_y_period, u, v */ 32209885543Smrg 0, 0, 0, /* vert_y_period, u, v */ 32309885543Smrg { 'R', 'V', 'B' }, /* component_order */ 32409885543Smrg XvTopToBottom /* scaline_order */ 32509885543Smrg }, 32609885543Smrg { 32709885543Smrg FOURCC_RV24, /* id */ 32809885543Smrg XvRGB, /* type */ 32909885543Smrg LSBFirst, /* byte_order */ 33009885543Smrg { 'R', 'V' ,'2', '4', 33109885543Smrg 0x00, 0x00, 0x00, 0x00, 33209885543Smrg 0x00, 0x00, 0x00, 0x00, 33309885543Smrg 0x00, 0x00, 0x00, 0x00 }, /* guid */ 33409885543Smrg 24, /* bits_per_pixel */ 33509885543Smrg XvPacked, /* format */ 33609885543Smrg 1, /* num_planes */ 33709885543Smrg 24, /* depth */ 33809885543Smrg 0x0000FF, 0x00FF00, 0xFF0000, /* red_mask, green, blue */ 33909885543Smrg 0, 0, 0, /* y_sample_bits, u, v */ 34009885543Smrg 0, 0, 0, /* horz_y_period, u, v */ 34109885543Smrg 0, 0, 0, /* vert_y_period, u, v */ 34209885543Smrg { 'R', 'V', 'B' }, /* component_order */ 34309885543Smrg XvTopToBottom /* scaline_order */ 34409885543Smrg }, 34509885543Smrg { 34609885543Smrg FOURCC_RV32, /* id */ 34709885543Smrg XvRGB, /* type */ 34809885543Smrg LSBFirst, /* byte_order */ 34909885543Smrg { 'R', 'V' ,'3', '2', 35009885543Smrg 0x00, 0x00, 0x00, 0x00, 35109885543Smrg 0x00, 0x00, 0x00, 0x00, 35209885543Smrg 0x00, 0x00, 0x00, 0x00 }, /* guid */ 35309885543Smrg 32, /* bits_per_pixel */ 35409885543Smrg XvPacked, /* format */ 35509885543Smrg 1, /* num_planes */ 35609885543Smrg 24, /* depth */ 35709885543Smrg 0x0000FF, 0x00FF00, 0xFF0000, /* red_mask, green, blue */ 35809885543Smrg 0, 0, 0, /* y_sample_bits, u, v */ 35909885543Smrg 0, 0, 0, /* horz_y_period, u, v */ 36009885543Smrg 0, 0, 0, /* vert_y_period, u, v */ 36109885543Smrg { 'R', 'V', 'B' }, /* component_order */ 36209885543Smrg XvTopToBottom /* scaline_order */ 36309885543Smrg }, 36409885543Smrg}; 36509885543Smrg 36609885543Smrg 36709885543Smrg/**************************************************************************/ 36809885543Smrg 36909885543Smrg/** 37009885543Smrg * SAA7111 video decoder register values 37109885543Smrg */ 37209885543Smrg 37309885543Smrg 37409885543Smrg/** SAA7111 control sequences for selecting one out of four 37509885543Smrg composite input channels */ 37609885543Smrgstatic I2CByte SAA7111CompositeChannelSelect[N_COMPOSITE_CHANNELS][4] = { 37709885543Smrg { 0x02, 0xC0, 0x09, 0x4A}, /* CVBS AI11 */ 37809885543Smrg { 0x02, 0xC1, 0x09, 0x4A}, /* CVBS AI12 */ 37909885543Smrg { 0x02, 0xC2, 0x09, 0x4A}, /* CVBS AI21 */ 38009885543Smrg { 0x02, 0xC3, 0x09, 0x4A}, /* CVBS AI22 */ 38109885543Smrg}; 38209885543Smrg 38309885543Smrg 38409885543Smrg/** SAA7111 control sequences for selecting one out of two 38509885543Smrg s-video input channels */ 38609885543Smrgstatic I2CByte SAA7111SVideoChannelSelect[N_SVIDEO_CHANNELS][4] = { 38709885543Smrg { 0x02, 0xC6, 0x09, 0xCA}, /* Y/C AI11/AI21 */ 38809885543Smrg { 0x02, 0xC7, 0x09, 0xCA}, /* Y/C AI12/AI22 */ 38909885543Smrg}; 39009885543Smrg 39109885543Smrg 39209885543Smrg/** SAA7111 control sequences for selecting one out of three 39309885543Smrg video norms */ 39409885543Smrgstatic I2CByte SAA7111VideoStd[3][8] = { 39509885543Smrg {0x06, 108, 0x07, 108, 0x08, 0x09, 0x0E, 0x01}, /* PAL */ 39609885543Smrg {0x06, 107, 0x07, 107, 0x08, 0x49, 0x0E, 0x01}, /* NTSC */ 39709885543Smrg {0x06, 108, 0x07, 108, 0x08, 0x01, 0x0E, 0x51} /* SECAM */ 39809885543Smrg}; 39909885543Smrg 40009885543Smrg 40109885543Smrg#if 0 40209885543Smrgstatic I2CByte SAA7110InitData[] = 40309885543Smrg{ 40409885543Smrg /* Configuration */ 40509885543Smrg 0x00, 0x4C, 0x01, 0x3C, 0x02, 0x00, 0x03, 0xEF, 40609885543Smrg 0x04, 0xBD, 0x05, 0xE2, 0x06, 0x00, 0x07, 0x00, 40709885543Smrg 0x08, 0xF8, 0x09, 0xF8, 0x0A, 0x60, 0x0B, 0x60, 40809885543Smrg 0x0C, 0x00, 0x0D, 0x80, 0x0E, 0x18, 0x0F, 0xD9, 40909885543Smrg 0x10, 0x00, 0x11, 0x2B, 0x12, 0x40, 0x13, 0x40, 41009885543Smrg 0x14, 0x42, 0x15, 0x1A, 0x16, 0xFF, 0x17, 0xDA, 41109885543Smrg 0x18, 0xE6, 0x19, 0x90, 0x20, 0xD9, 0x21, 0x16, 41209885543Smrg 0x22, 0x40, 0x23, 0x40, 0x24, 0x80, 0x25, 0x40, 41309885543Smrg 0x26, 0x80, 0x27, 0x4F, 0x28, 0xFE, 0x29, 0x01, 41409885543Smrg 0x2A, 0xCF, 0x2B, 0x0F, 0x2C, 0x03, 0x2D, 0x01, 41509885543Smrg 0x2E, 0x83, 0x2F, 0x03, 0x30, 0x40, 0x31, 0x35, 41609885543Smrg 0x32, 0x02, 0x33, 0x8C, 0x34, 0x03, 41709885543Smrg 41809885543Smrg /* NTSC */ 41909885543Smrg 0x11, 0x2B, 0x0F, 0xD9, 42009885543Smrg 42109885543Smrg /* RCA input connector */ 42209885543Smrg 0x06, 0x00, 0x0E, 0x18, 0x20, 0xD9, 0x21, 0x16, 42309885543Smrg 0x22, 0x40, 0x2C, 0x03, 42409885543Smrg 42509885543Smrg}; 42609885543Smrg#endif 42709885543Smrg 42809885543Smrgstatic I2CByte SAA7111InitData[] = 42909885543Smrg{ 43009885543Smrg 0x11, 0x1D, /* 0D D0=1: automatic colour killer off 43109885543Smrg D1=0: DMSD data to YUV output 43209885543Smrg D2=1: output enable H/V sync on 43309885543Smrg D3=1: output enable YUV data on */ 43409885543Smrg 0x02, 0xC0, /* Mode 0 */ 43509885543Smrg 0x03, 0x23, /* automatic gain */ 43609885543Smrg 0x04, 0x00, /* */ 43709885543Smrg 0x05, 0x00, /* */ 43809885543Smrg 0x06, 108, /* hor sync begin */ 43909885543Smrg 0x07, 108, /* hor sync stop */ 44009885543Smrg 0x08, 0x88, /* sync control: 44109885543Smrg D1-0=00: VNOI = normal mode 44209885543Smrg D2=0: PLL closed 44309885543Smrg D3=1: VTR mode 44409885543Smrg D7=1: automatic field detection */ 44509885543Smrg 0x09, 0x41, /* 4A luminance control */ 44609885543Smrg 0x0A, 0x80, /* brightness = 128 (CCIR level) */ 44709885543Smrg 0x0B, 0x40, /* contrast = 1.0 */ 44809885543Smrg 0x0C, 0x40, /* crominance = 1.0 (CCIR level) */ 44909885543Smrg 0x0D, 0x00, /* hue = 0 */ 45009885543Smrg 0x0E, 0x01, /* chroma bandwidth = nominal 45109885543Smrg fast colour time constant = nominal 45209885543Smrg chrom comp filter on 45309885543Smrg colour standard PAL BGHI, NTSC M */ 45409885543Smrg 0x10, 0x48, /* luminance delay compensation = 0 45509885543Smrg VRLN = 1 45609885543Smrg fine pos of hs = 0 45709885543Smrg output format = YUV 422 */ 45809885543Smrg 0x12, 0x00, /* 20 D5=1: VPO in tristate */ 45909885543Smrg 0x13, 0x00, 46009885543Smrg 0x15, 0x00, 46109885543Smrg 0x16, 0x00, 46209885543Smrg 0x17, 0x00, 46309885543Smrg 46409885543Smrg}; 46509885543Smrg 46609885543Smrg 46709885543Smrg/**************************************************************************/ 46809885543Smrg 46909885543Smrg/* To allow this ddx to work on 4_3_0 and above, we need to include this */ 47009885543Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) 47109885543Smrgstatic Bool 47209885543SmrgRegionsEqual( 47309885543Smrg RegionPtr A, 47409885543Smrg RegionPtr B 47509885543Smrg) 47609885543Smrg{ 47709885543Smrg int *dataA, *dataB; 47809885543Smrg int num; 47909885543Smrg 48009885543Smrg ENTER_PROC("RegionsEqual"); 48109885543Smrg 48209885543Smrg num = REGION_NUM_RECTS(A); 48309885543Smrg if (num != REGION_NUM_RECTS(B)) 48409885543Smrg { 48509885543Smrg LEAVE_PROC("RegionsEqual"); 48609885543Smrg return(FALSE); 48709885543Smrg } 48809885543Smrg 48909885543Smrg if ( (A->extents.x1 != B->extents.x1) 49009885543Smrg || (A->extents.y1 != B->extents.y1) 49109885543Smrg || (A->extents.x2 != B->extents.x2) 49209885543Smrg || (A->extents.y2 != B->extents.y2) 49309885543Smrg ) 49409885543Smrg { 49509885543Smrg LEAVE_PROC("RegionsEqual"); 49609885543Smrg return(FALSE); 49709885543Smrg } 49809885543Smrg 49909885543Smrg dataA = (int*) REGION_RECTS(A); 50009885543Smrg dataB = (int*) REGION_RECTS(B); 50109885543Smrg 50209885543Smrg while (num--) 50309885543Smrg { 50409885543Smrg if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) 50509885543Smrg { 50609885543Smrg return(FALSE); 50709885543Smrg } 50809885543Smrg dataA += 2; 50909885543Smrg dataB += 2; 51009885543Smrg } 51109885543Smrg 51209885543Smrg LEAVE_PROC("RegionsEqual"); 51309885543Smrg return(TRUE); 51409885543Smrg} 51509885543Smrg#endif 51609885543Smrg 51709885543Smrg 51809885543Smrg/** 51909885543Smrg * generates XF86VideoEncoding[i] with video norm norm, video input format 52009885543Smrg * input and video input channel channel 52109885543Smrg */ 52209885543Smrgstatic int 52309885543SmrgSMI_AddEncoding(XF86VideoEncodingPtr enc, int i, 52409885543Smrg int norm, int input, int channel) 52509885543Smrg{ 52609885543Smrg char* norm_string; 52709885543Smrg char* input_string; 52809885543Smrg char channel_string[20]; 52909885543Smrg 53009885543Smrg ENTER_PROC("SMI_AddEncoding"); 53109885543Smrg 53209885543Smrg norm_string = VideoNorms[norm].name; 53309885543Smrg input_string = VideoInputs[input].name; 53409885543Smrg sprintf(channel_string, "%d", channel); 53509885543Smrg enc[i].id = i; 53609885543Smrg enc[i].name = xalloc(strlen(norm_string) + 53709885543Smrg strlen(input_string) + 53809885543Smrg strlen(channel_string)+3); 53909885543Smrg if (NULL == enc[i].name) { 54009885543Smrg LEAVE_PROC("SMI_AddEncoding"); 54109885543Smrg return -1; 54209885543Smrg } 54309885543Smrg enc[i].width = VideoNorms[norm].Wa; 54409885543Smrg enc[i].height = VideoNorms[norm].Ha; 54509885543Smrg enc[i].rate = VideoNorms[norm].rate; 54609885543Smrg sprintf(enc[i].name,"%s-%s-%s", norm_string, input_string, channel_string); 54709885543Smrg 54809885543Smrg LEAVE_PROC("SMI_AddEncoding"); 54909885543Smrg return 0; 55009885543Smrg} 55109885543Smrg 55209885543Smrg 55309885543Smrg/** 55409885543Smrg * builds XF86VideoEncodings with all legal combinations of video norm, 55509885543Smrg * video input format and video input channel 55609885543Smrg */ 55709885543Smrgstatic void 55809885543SmrgSMI_BuildEncodings(SMI_PortPtr p) 55909885543Smrg{ 56009885543Smrg int ch, n; 56109885543Smrg 56209885543Smrg ENTER_PROC("SMI_BuildEncodings"); 56309885543Smrg 56409885543Smrg /* allocate memory for encoding array */ 56509885543Smrg p->enc = xalloc(sizeof(XF86VideoEncodingRec) * N_ENCODINGS); 56609885543Smrg if (NULL == p->enc) 56709885543Smrg goto fail; 56809885543Smrg memset(p->enc,0,sizeof(XF86VideoEncodingRec) * N_ENCODINGS); 56909885543Smrg /* allocate memory for video norm array */ 57009885543Smrg p->norm = xalloc(sizeof(int) * N_ENCODINGS); 57109885543Smrg if (NULL == p->norm) 57209885543Smrg goto fail; 57309885543Smrg memset(p->norm,0,sizeof(int) * N_ENCODINGS); 57409885543Smrg /* allocate memory for video input format array */ 57509885543Smrg p->input = xalloc(sizeof(int) * N_ENCODINGS); 57609885543Smrg if (NULL == p->input) 57709885543Smrg goto fail; 57809885543Smrg memset(p->input,0,sizeof(int) * N_ENCODINGS); 57909885543Smrg /* allocate memory for video channel number array */ 58009885543Smrg p->channel = xalloc(sizeof(int) * N_ENCODINGS); 58109885543Smrg if (NULL == p->channel) 58209885543Smrg goto fail; 58309885543Smrg memset(p->channel,0,sizeof(int) * N_ENCODINGS); 58409885543Smrg 58509885543Smrg /* fill arrays */ 58609885543Smrg p->nenc = 0; 58709885543Smrg for (ch = 0; ch < N_COMPOSITE_CHANNELS; ch++) { 58809885543Smrg for (n = 0; n < N_VIDEO_NORMS; n++) { 58909885543Smrg SMI_AddEncoding(p->enc, p->nenc, n, VID_COMPOSITE, ch); 59009885543Smrg p->norm[p->nenc] = n; 59109885543Smrg p->input[p->nenc] = VID_COMPOSITE; 59209885543Smrg p->channel[p->nenc] = ch; 59309885543Smrg p->nenc++; 59409885543Smrg } 59509885543Smrg } 59609885543Smrg for (ch = 0; ch < N_SVIDEO_CHANNELS; ch++) { 59709885543Smrg for (n = 0; n < N_VIDEO_NORMS; n++) { 59809885543Smrg SMI_AddEncoding(p->enc, p->nenc, n, VID_SVIDEO, ch); 59909885543Smrg p->norm[p->nenc] = n; 60009885543Smrg p->input[p->nenc] = VID_SVIDEO; 60109885543Smrg p->channel[p->nenc] = ch; 60209885543Smrg p->nenc++; 60309885543Smrg } 60409885543Smrg } 60509885543Smrg LEAVE_PROC("SMI_BuildEncodings"); 60609885543Smrg return; 60709885543Smrg 60809885543Smrg fail: 60909885543Smrg if (p->input) xfree(p->input); 61009885543Smrg p->input = NULL; 61109885543Smrg if (p->norm) xfree(p->norm); 61209885543Smrg p->norm = NULL; 61309885543Smrg if (p->channel) xfree(p->channel); 61409885543Smrg p->channel = NULL; 61509885543Smrg if (p->enc) xfree(p->enc); 61609885543Smrg p->enc = NULL; 61709885543Smrg p->nenc = 0; 61809885543Smrg LEAVE_PROC("SMI_BuildEncodings"); 61909885543Smrg} 62009885543Smrg 62109885543Smrg 62209885543Smrg/******************************************************************************\ 62309885543Smrg** ** 62409885543Smrg** X V E X T E N S I O N I N T E R F A C E ** 62509885543Smrg** ** 62609885543Smrg\******************************************************************************/ 62709885543Smrg 62809885543Smrgvoid 62909885543SmrgSMI_InitVideo(ScreenPtr pScreen) 63009885543Smrg{ 63109885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 63209885543Smrg SMIPtr psmi = SMIPTR(pScrn); 63309885543Smrg XF86VideoAdaptorPtr *ptrAdaptors, *newAdaptors = NULL; 63409885543Smrg XF86VideoAdaptorPtr newAdaptor = NULL; 63509885543Smrg int numAdaptors; 63609885543Smrg 63709885543Smrg ENTER_PROC("SMI_InitVideo"); 63809885543Smrg 63909885543Smrg numAdaptors = xf86XVListGenericAdaptors(pScrn, &ptrAdaptors); 64009885543Smrg 64109885543Smrg DEBUG((VERBLEV, "numAdaptors=%d\n", numAdaptors)); 64209885543Smrg 64309885543Smrg if (psmi->rotate == 0) 64409885543Smrg { 64509885543Smrg newAdaptor = SMI_SetupVideo(pScreen); 64609885543Smrg DEBUG((VERBLEV, "newAdaptor=%p\n", newAdaptor)); 64709885543Smrg SMI_InitOffscreenImages(pScreen); 64809885543Smrg } 64909885543Smrg 65009885543Smrg if (newAdaptor != NULL) { 65109885543Smrg if (numAdaptors == 0) { 65209885543Smrg numAdaptors = 1; 65309885543Smrg ptrAdaptors = &newAdaptor; 65409885543Smrg } else { 65509885543Smrg newAdaptors = xalloc((numAdaptors + 1) * 65609885543Smrg sizeof(XF86VideoAdaptorPtr*)); 65709885543Smrg if (newAdaptors != NULL) { 65809885543Smrg memcpy(newAdaptors, ptrAdaptors, 65909885543Smrg numAdaptors * sizeof(XF86VideoAdaptorPtr)); 66009885543Smrg newAdaptors[numAdaptors++] = newAdaptor; 66109885543Smrg ptrAdaptors = newAdaptors; 66209885543Smrg } 66309885543Smrg } 66409885543Smrg } 66509885543Smrg 66609885543Smrg if (numAdaptors != 0) { 66709885543Smrg DEBUG((VERBLEV, "ScreenInit %i\n",numAdaptors)); 66809885543Smrg xf86XVScreenInit(pScreen, ptrAdaptors, numAdaptors); 66909885543Smrg } 67009885543Smrg 67109885543Smrg if (newAdaptors != NULL) { 67209885543Smrg xfree(newAdaptors); 67309885543Smrg } 67409885543Smrg 67509885543Smrg LEAVE_PROC("SMI_InitVideo"); 67609885543Smrg} 67709885543Smrg 67809885543Smrg 67909885543Smrg/*************************************************************************/ 68009885543Smrg 68109885543Smrg/* 68209885543Smrg * Video codec controls 68309885543Smrg */ 68409885543Smrg 68509885543Smrg#if 0 68609885543Smrg/** 68709885543Smrg * scales value value of attribute i to range min, max 68809885543Smrg */ 68909885543Smrgstatic int 69009885543SmrgScale(int i, int value, int min, int max) 69109885543Smrg{ 69209885543Smrg return min + (value - SMI_VideoAttributes[i].min_value) * (max - min) / 69309885543Smrg (SMI_VideoAttributes[i].max_value - SMI_VideoAttributes[i].min_value); 69409885543Smrg} 69509885543Smrg#endif 69609885543Smrg/** 69709885543Smrg * sets video decoder attributes channel, encoding, brightness, contrast, saturation, hue 69809885543Smrg */ 69909885543Smrgstatic int 70009885543SmrgSetAttr(ScrnInfoPtr pScrn, int i, int value) 70109885543Smrg{ 70209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 70309885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 70409885543Smrg 70509885543Smrg if (i < XV_ENCODING || i > XV_HUE) 70609885543Smrg return BadMatch; 70709885543Smrg 70809885543Smrg /* clamps value to attribute range */ 70909885543Smrg value = CLAMP(value, SMI_VideoAttributes[i].min_value, 71009885543Smrg SMI_VideoAttributes[i].max_value); 71109885543Smrg 71209885543Smrg if (i == XV_BRIGHTNESS) { 71309885543Smrg int my_value = (value <= 128? value + 128 : value - 128); 71409885543Smrg SetKeyReg(pSmi, 0x5C, 0xEDEDED | (my_value << 24)); 71509885543Smrg } else if (pPort->I2CDev.SlaveAddr == SAA7110) { 71609885543Smrg return SetAttrSAA7110(pScrn, i, value); 71709885543Smrg } else if (pPort->I2CDev.SlaveAddr == SAA7111) { 71809885543Smrg return SetAttrSAA7111(pScrn, i, value); 71909885543Smrg } 72009885543Smrg#if 0 72109885543Smrg else { 72209885543Smrg return XvBadAlloc; 72309885543Smrg } 72409885543Smrg#endif 72509885543Smrg 72609885543Smrg return Success; 72709885543Smrg} 72809885543Smrg 72909885543Smrg 73009885543Smrg/** 73109885543Smrg * sets SAA7110 video decoder attributes channel, encoding, brightness, contrast, saturation, hue 73209885543Smrg */ 73309885543Smrgstatic int 73409885543SmrgSetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value) 73509885543Smrg{ 73609885543Smrg /* not supported */ 73709885543Smrg return XvBadAlloc; 73809885543Smrg} 73909885543Smrg 74009885543Smrg 74109885543Smrg/** 74209885543Smrg * sets SAA7111 video decoder attributes channel, encoding, 74309885543Smrg * brightness, contrast, saturation, hue 74409885543Smrg */ 74509885543Smrgstatic int 74609885543SmrgSetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value) 74709885543Smrg{ 74809885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 74909885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 75009885543Smrg 75109885543Smrg if (i == XV_ENCODING) { 75209885543Smrg int norm; 75309885543Smrg int input; 75409885543Smrg int channel; 75509885543Smrg norm = pPort->norm[value]; 75609885543Smrg input = pPort->input[value]; 75709885543Smrg channel = pPort->channel[value]; 75809885543Smrg 75909885543Smrg DEBUG((VERBLEV, "SetAttribute XV_ENCODING: %d. norm=%d input=%d channel=%d\n", 76009885543Smrg value, norm, input, channel)); 76109885543Smrg 76209885543Smrg /* set video norm */ 76309885543Smrg if (!xf86I2CWriteVec(&(pPort->I2CDev), SAA7111VideoStd[norm], 76409885543Smrg ENTRIES(SAA7111VideoStd[norm]) / 2)) { 76509885543Smrg return XvBadAlloc; 76609885543Smrg } 76709885543Smrg /* set video input format and channel */ 76809885543Smrg if (input == VID_COMPOSITE) { 76909885543Smrg if (!xf86I2CWriteVec(&(pPort->I2CDev), 77009885543Smrg SAA7111CompositeChannelSelect[channel], 77109885543Smrg ENTRIES(SAA7111CompositeChannelSelect[channel]) / 2)) { 77209885543Smrg return XvBadAlloc; 77309885543Smrg } 77409885543Smrg } else { 77509885543Smrg if (!xf86I2CWriteVec(&(pPort->I2CDev), 77609885543Smrg SAA7111SVideoChannelSelect[channel], 77709885543Smrg ENTRIES(SAA7111SVideoChannelSelect[channel]) / 2)) { 77809885543Smrg return XvBadAlloc; 77909885543Smrg } 78009885543Smrg } 78109885543Smrg } else if (i >= XV_CAPTURE_BRIGHTNESS && i <= XV_HUE) { 78209885543Smrg int slave_adr = 0; 78309885543Smrg 78409885543Smrg switch (i) { 78509885543Smrg 78609885543Smrg case XV_CAPTURE_BRIGHTNESS: 78709885543Smrg DEBUG((VERBLEV, "SetAttribute XV_BRIGHTNESS: %d\n", value)); 78809885543Smrg slave_adr = 0x0a; 78909885543Smrg break; 79009885543Smrg 79109885543Smrg case XV_CONTRAST: 79209885543Smrg DEBUG((VERBLEV, "SetAttribute XV_CONTRAST: %d\n", value)); 79309885543Smrg slave_adr = 0x0b; 79409885543Smrg break; 79509885543Smrg 79609885543Smrg case XV_SATURATION: 79709885543Smrg DEBUG((VERBLEV, "SetAttribute XV_SATURATION: %d\n", value)); 79809885543Smrg slave_adr = 0x0c; 79909885543Smrg break; 80009885543Smrg 80109885543Smrg case XV_HUE: 80209885543Smrg DEBUG((VERBLEV, "SetAttribute XV_HUE: %d\n", value)); 80309885543Smrg slave_adr = 0x0d; 80409885543Smrg break; 80509885543Smrg 80609885543Smrg default: 80709885543Smrg return XvBadAlloc; 80809885543Smrg } 80909885543Smrg if (!xf86I2CWriteByte(&(pPort->I2CDev), slave_adr, (value & 0xff))) 81009885543Smrg return XvBadAlloc; 81109885543Smrg } else { 81209885543Smrg return BadMatch; 81309885543Smrg } 81409885543Smrg 81509885543Smrg /* debug: show registers */ 81609885543Smrg { 81709885543Smrg I2CByte i2c_bytes[32]; 81809885543Smrg int i; 81909885543Smrg xf86I2CReadBytes(&(pPort->I2CDev), 0, i2c_bytes, 32); 82009885543Smrg DEBUG((VERBLEV, "SAA7111 Registers\n")); 82109885543Smrg for (i=0; i<32; i++) { 82209885543Smrg DEBUG((VERBLEV, "%02X=%02X ", i, i2c_bytes[i])); 82309885543Smrg if ((i&7) == 7) DEBUG((VERBLEV, "\n")); 82409885543Smrg } 82509885543Smrg } 82609885543Smrg 82709885543Smrg return Success; 82809885543Smrg} 82909885543Smrg 83009885543Smrg 83109885543Smrg/******************************************************************************\ 83209885543Smrg** ** 83309885543Smrg** V I D E O M A N A G E M E N T ** 83409885543Smrg** ** 83509885543Smrg\******************************************************************************/ 83609885543Smrg 83709885543Smrgstatic XF86VideoAdaptorPtr 83809885543SmrgSMI_SetupVideo(ScreenPtr pScreen) 83909885543Smrg{ 84009885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 84109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 84209885543Smrg SMI_PortPtr smiPortPtr; 84309885543Smrg XF86VideoAdaptorPtr ptrAdaptor; 84409885543Smrg 84509885543Smrg ENTER_PROC("SMI_SetupVideo"); 84609885543Smrg 84709885543Smrg ptrAdaptor = xcalloc(1, sizeof(XF86VideoAdaptorRec) + 84809885543Smrg sizeof(DevUnion) + sizeof(SMI_PortRec)); 84909885543Smrg if (ptrAdaptor == NULL) { 85009885543Smrg LEAVE_PROC("SMI_SetupVideo"); 85109885543Smrg return NULL; 85209885543Smrg } 85309885543Smrg 85409885543Smrg ptrAdaptor->type = XvInputMask 85509885543Smrg#if SMI_USE_CAPTURE 85609885543Smrg | XvOutputMask 85709885543Smrg | XvVideoMask 85809885543Smrg#endif 85909885543Smrg | XvImageMask 86009885543Smrg | XvWindowMask 86109885543Smrg ; 86209885543Smrg 86309885543Smrg ptrAdaptor->flags = VIDEO_OVERLAID_IMAGES 86409885543Smrg | VIDEO_CLIP_TO_VIEWPORT 86509885543Smrg ; 86609885543Smrg 86709885543Smrg ptrAdaptor->name = "Silicon Motion Lynx Series Video Engine"; 86809885543Smrg 86909885543Smrg ptrAdaptor->nPorts = 1; 87009885543Smrg ptrAdaptor->pPortPrivates = (DevUnion*) &ptrAdaptor[1]; 87109885543Smrg ptrAdaptor->pPortPrivates[0].ptr = (pointer) &ptrAdaptor->pPortPrivates[1]; 87209885543Smrg 87309885543Smrg smiPortPtr = (SMI_PortPtr) ptrAdaptor->pPortPrivates[0].ptr; 87409885543Smrg 87509885543Smrg SMI_BuildEncodings(smiPortPtr); 87609885543Smrg ptrAdaptor->nEncodings = smiPortPtr->nenc; 87709885543Smrg ptrAdaptor->pEncodings = smiPortPtr->enc; 87809885543Smrg#if 0 87909885543Smrg /* aaa whats this? */ 88009885543Smrg for (i = 0; i < nElems(SMI_VideoEncodings); i++) 88109885543Smrg { 88209885543Smrg SMI_VideoEncodings[i].width = pSmi->lcdWidth; 88309885543Smrg SMI_VideoEncodings[i].height = pSmi->lcdHeight; 88409885543Smrg } 88509885543Smrg#endif 88609885543Smrg 88709885543Smrg ptrAdaptor->nFormats = nElems(SMI_VideoFormats); 88809885543Smrg ptrAdaptor->pFormats = SMI_VideoFormats; 88909885543Smrg 89009885543Smrg ptrAdaptor->nAttributes = nElems(SMI_VideoAttributes); 89109885543Smrg ptrAdaptor->pAttributes = SMI_VideoAttributes; 89209885543Smrg 89309885543Smrg ptrAdaptor->nImages = nElems(SMI_VideoImages); 89409885543Smrg ptrAdaptor->pImages = SMI_VideoImages; 89509885543Smrg 89609885543Smrg#if SMI_USE_CAPTURE 89709885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) 89809885543Smrg ptrAdaptor->PutVideo = NULL; 89909885543Smrg else 90009885543Smrg ptrAdaptor->PutVideo = SMI_PutVideo; 90109885543Smrg ptrAdaptor->PutStill = NULL; 90209885543Smrg ptrAdaptor->GetVideo = NULL; 90309885543Smrg ptrAdaptor->GetStill = NULL; 90409885543Smrg#else 90509885543Smrg ptrAdaptor->PutVideo = NULL; 90609885543Smrg ptrAdaptor->PutStill = NULL; 90709885543Smrg ptrAdaptor->GetVideo = NULL; 90809885543Smrg ptrAdaptor->GetStill = NULL; 90909885543Smrg#endif 91009885543Smrg ptrAdaptor->StopVideo = SMI_StopVideo; 91109885543Smrg ptrAdaptor->SetPortAttribute = SMI_SetPortAttribute; 91209885543Smrg ptrAdaptor->GetPortAttribute = SMI_GetPortAttribute; 91309885543Smrg ptrAdaptor->QueryBestSize = SMI_QueryBestSize; 91409885543Smrg ptrAdaptor->PutImage = SMI_PutImage; 91509885543Smrg ptrAdaptor->QueryImageAttributes = SMI_QueryImageAttributes; 91609885543Smrg 91709885543Smrg smiPortPtr->Attribute[XV_COLORKEY] = pSmi->videoKey; 91809885543Smrg smiPortPtr->Attribute[XV_INTERLACED] = pSmi->interlaced; 91909885543Smrg smiPortPtr->videoStatus = 0; 92009885543Smrg 92109885543Smrg#if 0 92209885543Smrg /* aaa does not work ? */ 92309885543Smrg if (xf86I2CProbeAddress(pSmi->I2C, SAA7111)) 92409885543Smrg { 92509885543Smrg LEAVE_PROC("SMI_SetupVideo"); 92609885543Smrg return(NULL); 92709885543Smrg } 92809885543Smrg DEBUG((VERBLEV, "SAA7111 detected\n")); 92909885543Smrg#endif 93009885543Smrg 93109885543Smrg smiPortPtr->I2CDev.DevName = "SAA 7111A"; 93209885543Smrg smiPortPtr->I2CDev.SlaveAddr = SAA7111; 93309885543Smrg smiPortPtr->I2CDev.pI2CBus = pSmi->I2C; 93409885543Smrg 93509885543Smrg 93609885543Smrg if (xf86I2CDevInit(&(smiPortPtr->I2CDev))) { 93709885543Smrg 93809885543Smrg if (xf86I2CWriteVec(&(smiPortPtr->I2CDev), SAA7111InitData, ENTRIES(SAA7111InitData) / 2)) { 93909885543Smrg xvEncoding = MAKE_ATOM(XV_ENCODING_NAME); 94009885543Smrg xvHue = MAKE_ATOM(XV_HUE_NAME); 94109885543Smrg xvSaturation = MAKE_ATOM(XV_SATURATION_NAME); 94209885543Smrg xvContrast = MAKE_ATOM(XV_CONTRAST_NAME); 94309885543Smrg 94409885543Smrg xvInterlaced = MAKE_ATOM(XV_INTERLACED_NAME); 94509885543Smrg DEBUG((VERBLEV, "SAA7111 intialized\n")); 94609885543Smrg 94709885543Smrg } else { 94809885543Smrg xf86DestroyI2CDevRec(&(smiPortPtr->I2CDev),FALSE); 94909885543Smrg smiPortPtr->I2CDev.SlaveAddr = 0; 95009885543Smrg } 95109885543Smrg } else 95209885543Smrg smiPortPtr->I2CDev.SlaveAddr = 0; 95309885543Smrg 95409885543Smrg#if defined(REGION_NULL) 95509885543Smrg REGION_NULL(pScreen, &smiPortPtr->clip); 95609885543Smrg#else 95709885543Smrg REGION_INIT(pScreen, &smiPortPtr->clip, NullBox, 0); 95809885543Smrg#endif 95909885543Smrg 96009885543Smrg pSmi->ptrAdaptor = ptrAdaptor; 96109885543Smrg pSmi->BlockHandler = pScreen->BlockHandler; 96209885543Smrg pScreen->BlockHandler = SMI_BlockHandler; 96309885543Smrg 96409885543Smrg xvColorKey = MAKE_ATOM(XV_COLORKEY_NAME); 96509885543Smrg xvBrightness = MAKE_ATOM(XV_BRIGHTNESS_NAME); 96609885543Smrg xvCapBrightness = MAKE_ATOM(XV_CAPTURE_BRIGHTNESS_NAME); 96709885543Smrg 96809885543Smrg SMI_ResetVideo(pScrn); 96909885543Smrg LEAVE_PROC("SMI_SetupVideo"); 97009885543Smrg return ptrAdaptor; 97109885543Smrg} 97209885543Smrg 97309885543Smrg 97409885543Smrgstatic void 97509885543SmrgSMI_ResetVideo(ScrnInfoPtr pScrn) 97609885543Smrg{ 97709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 97809885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 97909885543Smrg int r, g, b; 98009885543Smrg 98109885543Smrg ENTER_PROC("SMI_ResetVideo"); 98209885543Smrg 98309885543Smrg SetAttr(pScrn, XV_ENCODING, 0); /* Encoding = pal-composite-0 */ 98409885543Smrg SetAttr(pScrn, XV_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */ 98509885543Smrg SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */ 98609885543Smrg SetAttr(pScrn, XV_CONTRAST, 71); /* Contrast = 71 (CCIR level) */ 98709885543Smrg SetAttr(pScrn, XV_SATURATION, 64); /* Color saturation = 64 (CCIR level) */ 98809885543Smrg SetAttr(pScrn, XV_HUE, 0); /* Hue = 0 */ 98909885543Smrg 99009885543Smrg switch (pScrn->depth) { 99109885543Smrg case 8: 99209885543Smrg SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0x00FF); 99309885543Smrg SetKeyReg(pSmi, FPR08, 0); 99409885543Smrg break; 99509885543Smrg case 15: 99609885543Smrg case 16: 99709885543Smrg SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0xFFFF); 99809885543Smrg SetKeyReg(pSmi, FPR08, 0); 99909885543Smrg break; 100009885543Smrg default: 100109885543Smrg r = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.red) >> pScrn->offset.red; 100209885543Smrg g = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.green) >> pScrn->offset.green; 100309885543Smrg b = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.blue) >> pScrn->offset.blue; 100409885543Smrg SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); 100509885543Smrg SetKeyReg(pSmi, FPR08, 0); 100609885543Smrg break; 100709885543Smrg } 100809885543Smrg 100909885543Smrg SetKeyReg(pSmi, FPR5C, 0xEDEDED | (pPort->Attribute[XV_BRIGHTNESS] << 24)); 101009885543Smrg 101109885543Smrg LEAVE_PROC("SMI_ResetVideo"); 101209885543Smrg} 101309885543Smrg 101409885543Smrg 101509885543Smrg#if SMI_USE_CAPTURE 101609885543Smrgstatic int 101709885543SmrgSMI_PutVideo( 101809885543Smrg ScrnInfoPtr pScrn, 101909885543Smrg short vid_x, 102009885543Smrg short vid_y, 102109885543Smrg short drw_x, 102209885543Smrg short drw_y, 102309885543Smrg short vid_w, 102409885543Smrg short vid_h, 102509885543Smrg short drw_w, 102609885543Smrg short drw_h, 102709885543Smrg RegionPtr clipBoxes, 102809885543Smrg pointer data, 102909885543Smrg DrawablePtr pDraw 103009885543Smrg) 103109885543Smrg{ 103209885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 103309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 103409885543Smrg CARD32 vid_pitch, vid_address; 103509885543Smrg CARD32 vpr00, cpr00; 103609885543Smrg int xscale, yscale; 103709885543Smrg BoxRec dstBox; 103809885543Smrg INT32 x1, y1, x2, y2; 103909885543Smrg int norm; 104009885543Smrg int size, width, height, fbPitch; 104109885543Smrg int top, left; 104209885543Smrg 104309885543Smrg ENTER_PROC("SMI_PutVideo"); 104409885543Smrg 104509885543Smrg DEBUG((VERBLEV, "Interlaced Video %d\n", pPort->Attribute[XV_INTERLACED])); 104609885543Smrg 104709885543Smrg if (!pPort->Attribute[XV_INTERLACED]) { 104809885543Smrg /* no interlace: lines will be doubled */ 104909885543Smrg vid_h /= 2; 105009885543Smrg } 105109885543Smrg 105209885543Smrg /* field start aaa*/ 105309885543Smrg norm = pPort->norm[pPort->Attribute[XV_ENCODING]]; 105409885543Smrg vid_x += VideoNorms[norm].HStart; 105509885543Smrg vid_y += VideoNorms[norm].VStart; 105609885543Smrg /* only even values allowed (UV-phase) */ 105709885543Smrg vid_x &= ~1; 105809885543Smrg 105909885543Smrg DEBUG((VERBLEV, "vid_x=%d vid_y=%d drw_x=%d drw_y=%d " 106009885543Smrg "vid_w=%d vid_h=%d drw_w=%d drw_h=%d\n", 106109885543Smrg vid_x, vid_y, drw_x, drw_y, vid_w, vid_h, drw_w, drw_h)); 106209885543Smrg 106309885543Smrg x1 = vid_x; 106409885543Smrg y1 = vid_y; 106509885543Smrg x2 = vid_x + vid_w; 106609885543Smrg y2 = vid_y + vid_h; 106709885543Smrg 106809885543Smrg width = vid_w; 106909885543Smrg height = vid_h; 107009885543Smrg 107109885543Smrg dstBox.x1 = drw_x; 107209885543Smrg dstBox.y1 = drw_y; 107309885543Smrg dstBox.x2 = drw_x + drw_w; 107409885543Smrg dstBox.y2 = drw_y + drw_h; 107509885543Smrg 107609885543Smrg#if 1 107709885543Smrg if (!SMI_ClipVideo(pScrn, &dstBox, &x1, &y1, &x2, &y2, clipBoxes, width, height)) { 107809885543Smrg#else 107909885543Smrg if (!xf86XVClipVideoHelper(&dstBox, &x1, &y1, &x2, &y2, clipBoxes, width, height)) { 108009885543Smrg#endif 108109885543Smrg LEAVE_PROC("SMI_PutVideo"); 108209885543Smrg return Success; 108309885543Smrg } 108409885543Smrg 108509885543Smrg DEBUG((VERBLEV, "Clip: x1=%d y1=%d x2=%d y2=%d\n", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16)); 108609885543Smrg 108709885543Smrg dstBox.x1 -= pScrn->frameX0; 108809885543Smrg dstBox.y1 -= pScrn->frameY0; 108909885543Smrg dstBox.x2 -= pScrn->frameX0; 109009885543Smrg dstBox.y2 -= pScrn->frameY0; 109109885543Smrg 109209885543Smrg vid_pitch = (vid_w * 2 + 7) & ~7; 109309885543Smrg 109409885543Smrg vpr00 = READ_VPR(pSmi, 0x00) & ~0x0FF000FF; 109509885543Smrg cpr00 = READ_CPR(pSmi, 0x00) & ~0x000FFF00; 109609885543Smrg 109709885543Smrg /* vpr00: 109809885543Smrg Bit 2..0 = 6: Video Window I Format = YUV4:2:2 109909885543Smrg Bit 3 = 1: Video Window I Enable = enabled 110009885543Smrg Bit 4 = 0: Video Window I YUV Averaging = disabled 110109885543Smrg Bit 5 = 0: Video Window I Hor. Replication = disabled 110209885543Smrg Bit 6 = 0: Video Window I data doubling = disabled 110309885543Smrg Bit 14..8 = 0: Video Window II = disabled 110409885543Smrg Bit 18..16 = 0: Graphics Data Format = 8-bit index 110509885543Smrg Bit 19 = 0: Top Video Window Select = window I 110609885543Smrg Bit 20 = 1: Color Key for Window I = enabled 110709885543Smrg Bit 21 = 0: Vertical Interpolation = s. below 110809885543Smrg Bit 22 = 0: Flicker Reduction for TV Modes = disabled 110909885543Smrg Bit 23 = 0: Fixed Vertical Interpolation = disabled 111009885543Smrg Bit 24 = 1: Select Video Window I Source Addr = 111109885543Smrg Bit 25 = 0: Enable V0FIFO to fetch 8-Bit color data = disabled 111209885543Smrg Bit 26 = 0: 111309885543Smrg Bit 27 = 1: Color Key for Window II = disabled 111409885543Smrg Bit 31..28 = reserved 111509885543Smrg */ 111609885543Smrg if (pPort->Attribute[XV_INTERLACED]) { 111709885543Smrg /* 111809885543Smrg Bit 21 = 0: Vertical Interpolation = disabled 111909885543Smrg Bit 24 = 0: Select Video Window I Source Addr = 0 112009885543Smrg */ 112109885543Smrg vpr00 |= 0x0010000E; 112209885543Smrg } else { 112309885543Smrg /* 112409885543Smrg Bit 21 = 10: Vertical Interpolation = enabled 112509885543Smrg Bit 24 = 1: Select Video Window I Source Addr = 1 112609885543Smrg 1= Video window I source addr = capture port buffer ? 112709885543Smrg */ 112809885543Smrg vpr00 |= 0x0130000E; 112909885543Smrg } 113009885543Smrg 113109885543Smrg /* cpr00: 113209885543Smrg Bit 0 = 1: Video Capture Enable = enabled 113309885543Smrg Bit 8 = 0: Capture Control = continous 113409885543Smrg Bit 9 = 0: Double Buffer Enable = s. below 113509885543Smrg Bit 10 = 0: Interlace Data Capture = s. below 113609885543Smrg Bit 13..11 = 0: Frame Skip Enable = s. below 113709885543Smrg Bit 15..14 = 0: Video Capture Input Format = YUV4:2:2 113809885543Smrg Bit 17..16 = 0: Enable Hor. Reduction = s. below 113909885543Smrg Bit 19..18 = 0: Enable Vert. Reduction = s. below 114009885543Smrg Bit 21..20 = 0: Enable Hor. Filtering = s. below 114109885543Smrg Bit 22 = 0: HREF Polarity = high active 114209885543Smrg Bit 23 = 0: VREF Polarity = high active 114309885543Smrg Bit 24 = 1: Field Detection Method VSYNC edge = rising 114409885543Smrg */ 114509885543Smrg if (pPort->Attribute[XV_INTERLACED]) { 114609885543Smrg /* 114709885543Smrg Bit 9 = 1: Double Buffer Enable = enabled 114809885543Smrg Bit 10 = 1: Interlace Data Capture = enabled 114909885543Smrg Bit 13..11 = 0: Frame Skip Enable = no skip 115009885543Smrg */ 115109885543Smrg cpr00 |= 0x01000601; 115209885543Smrg } else { 115309885543Smrg /* 115409885543Smrg Bit 9 = 0: Double Buffer Enable = disabled 115509885543Smrg Bit 10 = 0: Interlace Data Capture = disabled 115609885543Smrg Bit 13..11 = 010: Frame Skip Enable = skip every other frame 115709885543Smrg */ 115809885543Smrg cpr00 |= 0x01000801; 115909885543Smrg } 116009885543Smrg 116109885543Smrg if (pSmi->ByteSwap) 116209885543Smrg cpr00 |= 0x00004000; 116309885543Smrg 116409885543Smrg fbPitch = pSmi->Stride; 116509885543Smrg if (pSmi->Bpp != 3) { 116609885543Smrg fbPitch *= pSmi->Bpp; 116709885543Smrg } 116809885543Smrg 116909885543Smrg if (vid_w <= drw_w) { 117009885543Smrg xscale = (256 * vid_w / drw_w) & 0xFF; 117109885543Smrg } else if (vid_w / 2 <= drw_w) { 117209885543Smrg xscale = (128 * vid_w / drw_w) & 0xFF; 117309885543Smrg width /= 2; 117409885543Smrg vid_pitch /= 2; 117509885543Smrg cpr00 |= 0x00010000; 117609885543Smrg } else if (vid_w / 4 <= drw_w) { 117709885543Smrg xscale = (64 * vid_w / drw_w) & 0xFF; 117809885543Smrg width /= 4; 117909885543Smrg vid_pitch /= 4; 118009885543Smrg cpr00 |= 0x00020000; 118109885543Smrg } else { 118209885543Smrg xscale = 0; 118309885543Smrg width /= 4; 118409885543Smrg vid_pitch /= 4; 118509885543Smrg cpr00 |= 0x00020000; 118609885543Smrg } 118709885543Smrg 118809885543Smrg if (vid_h <= drw_h) { 118909885543Smrg yscale = (256 * vid_h / drw_h) & 0xFF; 119009885543Smrg } else if (vid_h / 2 <= drw_h) { 119109885543Smrg yscale = (128 * vid_h / drw_h) & 0xFF; 119209885543Smrg height /= 2; 119309885543Smrg cpr00 |= 0x00040000; 119409885543Smrg } else if (vid_h / 4 <= drw_h) { 119509885543Smrg yscale = (64 * vid_h / drw_h) & 0xFF; 119609885543Smrg height /= 4; 119709885543Smrg cpr00 |= 0x00080000; 119809885543Smrg } else { 119909885543Smrg yscale = 0; 120009885543Smrg height /= 4; 120109885543Smrg cpr00 |= 0x00080000; 120209885543Smrg } 120309885543Smrg 120409885543Smrg do { 120509885543Smrg size = vid_pitch * height; 120609885543Smrg DEBUG((VERBLEV, "SMI_AllocateMemory: vid_pitch=%d height=%d size=%d\n", 120709885543Smrg vid_pitch, height, size)); 120809885543Smrg pPort->video_offset = SMI_AllocateMemory(pScrn, &pPort->video_memory, size); 120909885543Smrg if (pPort->video_offset == 0) { 121009885543Smrg if ((cpr00 & 0x000C0000) == 0) { 121109885543Smrg /* height -> 1/2 height */ 121209885543Smrg yscale = (128 * vid_h / drw_h) & 0xFF; 121309885543Smrg height = vid_h / 2; 121409885543Smrg cpr00 |= 0x00040000; 121509885543Smrg } else if (cpr00 & 0x00040000) { 121609885543Smrg /* 1/2 height -> 1/4 height */ 121709885543Smrg yscale = (64 * vid_h / drw_h) & 0xFF; 121809885543Smrg height = vid_h / 4; 121909885543Smrg cpr00 ^= 0x000C0000; 122009885543Smrg } else { 122109885543Smrg /* 1/4 height */ 122209885543Smrg if ((cpr00 & 0x00030000) == 0) { 122309885543Smrg /* width -> 1/2 width */ 122409885543Smrg xscale = (128 * vid_w / drw_w) & 0xFF; 122509885543Smrg width = vid_w / 2; 122609885543Smrg cpr00 |= 0x00010000; 122709885543Smrg } else if (cpr00 & 0x00010000) { 122809885543Smrg /* 1/2 width -> 1/4 width */ 122909885543Smrg xscale = (64 * vid_w / drw_w) & 0xFF; 123009885543Smrg width = vid_w / 4; 123109885543Smrg cpr00 ^= 0x00030000; 123209885543Smrg } else { 123309885543Smrg DEBUG((VERBLEV, "allocate error\n")); 123409885543Smrg LEAVE_PROC("SMI_PutVideo"); 123509885543Smrg return BadAlloc; 123609885543Smrg } 123709885543Smrg } 123809885543Smrg } 123909885543Smrg } while (pPort->video_offset == 0); 124009885543Smrg 124109885543Smrg DEBUG((VERBLEV, "xscale==%d yscale=%d width=%d height=%d\n", 124209885543Smrg xscale, yscale, width, height)); 124309885543Smrg 124409885543Smrg /* aaa whats this ----------------------v ? 124509885543Smrg vid_address = (pPort->area->box.y1 * fbPitch) + ((y1 >> 16) * vid_pitch);*/ 124609885543Smrg vid_address = pPort->video_offset; 124709885543Smrg 124809885543Smrg DEBUG((VERBLEV, "test RegionsEqual\n")); 124909885543Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) 125009885543Smrg if (!RegionsEqual(&pPort->clip, clipBoxes)) 125109885543Smrg#else 125209885543Smrg if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) 125309885543Smrg#endif 125409885543Smrg { 125509885543Smrg DEBUG((VERBLEV, "RegionCopy\n")); 125609885543Smrg REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); 125709885543Smrg DEBUG((VERBLEV, "FillKey\n")); 125809885543Smrg xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes); 125909885543Smrg 126009885543Smrg } 126109885543Smrg 126209885543Smrg left = x1 >> 16; 126309885543Smrg top = y1 >> 16; 126409885543Smrg width = (x2 - x1) >> 16; 126509885543Smrg height = (y2 - y1) >> 16; 126609885543Smrg 126709885543Smrg OUT_SEQ(pSmi, 0x21, IN_SEQ(pSmi, 0x21) & ~0x04); 126809885543Smrg WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) | 0x00200000); 126909885543Smrg#if 0 127009885543Smrg SMI_WaitForSync(pScrn); 127109885543Smrg#endif 127209885543Smrg /* Video Window I Left and Top Boundaries */ 127309885543Smrg WRITE_VPR(pSmi, 0x14, dstBox.x1 + (dstBox.y1 << 16)); 127409885543Smrg /* Video Window I Right and Bottom Boundaries */ 127509885543Smrg WRITE_VPR(pSmi, 0x18, dstBox.x2 + (dstBox.y2 << 16)); 127609885543Smrg /* Video Window I Source Width and Offset */ 127709885543Smrg WRITE_VPR(pSmi, 0x20, (vid_pitch / 8) + ((vid_pitch / 8) << 16)); 127809885543Smrg /* Video Window I Stretch Factor */ 127909885543Smrg WRITE_VPR(pSmi, 0x24, (xscale << 8) + yscale); 128009885543Smrg 128109885543Smrg if (pPort->Attribute[XV_INTERLACED]) { 128209885543Smrg /* Video Window II Left and Top Boundaries */ 128309885543Smrg WRITE_VPR(pSmi, 0x28, dstBox.x1 + (dstBox.y1 << 16)); 128409885543Smrg /* Video Window II Right and Bottom Boundaries */ 128509885543Smrg WRITE_VPR(pSmi, 0x2C, dstBox.x2 + (dstBox.y2 << 16)); 128609885543Smrg /* Video Window II Source Width and Offset */ 128709885543Smrg WRITE_VPR(pSmi, 0x34, (vid_pitch / 8) + ((vid_pitch / 8) << 16)); 128809885543Smrg /* Video Window II Stretch Factor */ 128909885543Smrg WRITE_VPR(pSmi, 0x38, (xscale << 8) + yscale); 129009885543Smrg 129109885543Smrg /* Video Window I Source Start Address */ 129209885543Smrg WRITE_VPR(pSmi, 0x1C, vid_address / 8); 129309885543Smrg /* Video Window II Source Start Address */ 129409885543Smrg WRITE_VPR(pSmi, 0x30, vid_address / 8); 129509885543Smrg 129609885543Smrg /* Video Window I Source Start Address */ 129709885543Smrg WRITE_VPR(pSmi, 0x48, vid_address / 8); 129809885543Smrg /* Video Window II Source Start Address */ 129909885543Smrg WRITE_VPR(pSmi, 0x4C, vid_address / 8 + vid_pitch / 8); 130009885543Smrg 130109885543Smrg /* Video Source Clipping Control */ 130209885543Smrg WRITE_CPR(pSmi, 0x04, left + ((top/2) << 16)); 130309885543Smrg /* Video Source Capture Size Control */ 130409885543Smrg WRITE_CPR(pSmi, 0x08, width + ((height/2) << 16)); 130509885543Smrg /* Capture Port Buffer I Source Start Address */ 130609885543Smrg WRITE_CPR(pSmi, 0x0C, vid_address / 8); 130709885543Smrg /* Capture Port Buffer II Source Start Address */ 130809885543Smrg WRITE_CPR(pSmi, 0x10, vid_address / 8 + vid_pitch / 8); 130909885543Smrg /* Capture Port Source Offset Address */ 131009885543Smrg WRITE_CPR(pSmi, 0x14, 2*(vid_pitch / 8) + ((2*(vid_pitch / 8)) << 16)); 131109885543Smrg } else { 131209885543Smrg /* Video Source Clipping Control */ 131309885543Smrg WRITE_CPR(pSmi, 0x04, left + (top << 16)); 131409885543Smrg /* Video Source Capture Size Control */ 131509885543Smrg WRITE_CPR(pSmi, 0x08, width + (height << 16)); 131609885543Smrg /* Capture Port Buffer I Source Start Address */ 131709885543Smrg WRITE_CPR(pSmi, 0x0C, vid_address / 8); 131809885543Smrg /* Capture Port Buffer II Source Start Address */ 131909885543Smrg WRITE_CPR(pSmi, 0x10, vid_address / 8); 132009885543Smrg /* Capture Port Source Offset Address */ 132109885543Smrg WRITE_CPR(pSmi, 0x14, (vid_pitch / 8) + ((vid_pitch / 8) << 16)); 132209885543Smrg } 132309885543Smrg 132409885543Smrg WRITE_CPR(pSmi, 0x00, cpr00); 132509885543Smrg WRITE_VPR(pSmi, 0x00, vpr00); 132609885543Smrg 132709885543Smrg pPort->videoStatus = CLIENT_VIDEO_ON; 132809885543Smrg DEBUG((VERBLEV, "SMI_PutVideo success\n")); 132909885543Smrg LEAVE_PROC("SMI_PutVideo"); 133009885543Smrg return Success; 133109885543Smrg} 133209885543Smrg#endif 133309885543Smrg 133409885543Smrg 133509885543Smrgstatic void 133609885543SmrgSMI_StopVideo( 133709885543Smrg ScrnInfoPtr pScrn, 133809885543Smrg pointer data, 133909885543Smrg Bool shutdown 134009885543Smrg) 134109885543Smrg{ 134209885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 134309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 134409885543Smrg 134509885543Smrg ENTER_PROC("SMI_StopVideo"); 134609885543Smrg 134709885543Smrg REGION_EMPTY(pScrn->pScreen, &pPort->clip); 134809885543Smrg 134909885543Smrg if (shutdown) { 135009885543Smrg if (pPort->videoStatus & CLIENT_VIDEO_ON) { 135109885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 135209885543Smrg WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); 135309885543Smrg } else { 135409885543Smrg WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x01000008); 135509885543Smrg } 135609885543Smrg#if SMI_USE_CAPTURE 135709885543Smrg if (pSmi->Chipset != SMI_COUGAR3DR) { 135809885543Smrg WRITE_CPR(pSmi, 0x00, READ_CPR(pSmi, 0x00) & ~0x00000001); 135909885543Smrg WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) & ~0x00F00000); 136009885543Smrg } 136109885543Smrg/* #864 OUT_SEQ(pSmi, 0x21, IN_SEQ(pSmi, 0x21) | 0x04); */ 136209885543Smrg#endif 136309885543Smrg } 136409885543Smrg if (pPort->video_memory != NULL) { 136509885543Smrg SMI_FreeMemory(pScrn, pPort->video_memory); 136609885543Smrg pPort->video_memory = NULL; 136709885543Smrg } 136809885543Smrg pPort->videoStatus = 0; 136909885543Smrg /* pPort->i2cDevice = 0;aaa*/ 137009885543Smrg } else { 137109885543Smrg if (pPort->videoStatus & CLIENT_VIDEO_ON) { 137209885543Smrg pPort->videoStatus |= OFF_TIMER; 137309885543Smrg pPort->offTime = currentTime.milliseconds + OFF_DELAY; 137409885543Smrg } 137509885543Smrg } 137609885543Smrg 137709885543Smrg LEAVE_PROC("SMI_StopVideo"); 137809885543Smrg} 137909885543Smrg 138009885543Smrgstatic int 138109885543SmrgSMI_SetPortAttribute( 138209885543Smrg ScrnInfoPtr pScrn, 138309885543Smrg Atom attribute, 138409885543Smrg INT32 value, 138509885543Smrg pointer data 138609885543Smrg) 138709885543Smrg{ 138809885543Smrg int res; 138909885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 139009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 139109885543Smrg 139209885543Smrg ENTER_PROC("SMI_SetPortAttribute"); 139309885543Smrg 139409885543Smrg if (attribute == xvColorKey) { 139509885543Smrg int r, g, b; 139609885543Smrg 139709885543Smrg pPort->Attribute[XV_COLORKEY] = value; 139809885543Smrg switch (pScrn->depth) { 139909885543Smrg case 8: 140009885543Smrg SetKeyReg(pSmi, FPR04, value & 0x00FF); 140109885543Smrg break; 140209885543Smrg case 15: 140309885543Smrg case 16: 140409885543Smrg SetKeyReg(pSmi, FPR04, value & 0xFFFF); 140509885543Smrg break; 140609885543Smrg default: 140709885543Smrg r = (value & pScrn->mask.red) >> pScrn->offset.red; 140809885543Smrg g = (value & pScrn->mask.green) >> pScrn->offset.green; 140909885543Smrg b = (value & pScrn->mask.blue) >> pScrn->offset.blue; 141009885543Smrg SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); 141109885543Smrg break; 141209885543Smrg } 141309885543Smrg res = Success; 141409885543Smrg } else if (attribute == xvInterlaced) { 141509885543Smrg pPort->Attribute[XV_INTERLACED] = (value != 0); 141609885543Smrg res = Success; 141709885543Smrg } else if (attribute == xvEncoding) { 141809885543Smrg res = SetAttr(pScrn, XV_ENCODING, value); 141909885543Smrg } else if (attribute == xvBrightness) { 142009885543Smrg res = SetAttr(pScrn, XV_BRIGHTNESS, value); 142109885543Smrg } else if (attribute == xvCapBrightness) { 142209885543Smrg res = SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, value); 142309885543Smrg } else if (attribute == xvContrast) { 142409885543Smrg res = SetAttr(pScrn, XV_CONTRAST, value); 142509885543Smrg } else if (attribute == xvSaturation) { 142609885543Smrg res = SetAttr(pScrn, XV_SATURATION, value); 142709885543Smrg } else if (attribute == xvHue) { 142809885543Smrg res = SetAttr(pScrn, XV_HUE, value); 142909885543Smrg } else { 143009885543Smrg res = BadMatch; 143109885543Smrg } 143209885543Smrg 143309885543Smrg LEAVE_PROC("SMI_SetPortAttribute"); 143409885543Smrg return res; 143509885543Smrg} 143609885543Smrg 143709885543Smrg 143809885543Smrgstatic int 143909885543SmrgSMI_GetPortAttribute( 144009885543Smrg ScrnInfoPtr pScrn, 144109885543Smrg Atom attribute, 144209885543Smrg INT32 *value, 144309885543Smrg pointer data 144409885543Smrg) 144509885543Smrg{ 144609885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 144709885543Smrg 144809885543Smrg ENTER_PROC("SMI_GetPortAttribute"); 144909885543Smrg if (attribute == xvEncoding) 145009885543Smrg *value = pPort->Attribute[XV_ENCODING]; 145109885543Smrg else if (attribute == xvBrightness) 145209885543Smrg *value = pPort->Attribute[XV_BRIGHTNESS]; 145309885543Smrg else if (attribute == xvCapBrightness) 145409885543Smrg *value = pPort->Attribute[XV_CAPTURE_BRIGHTNESS]; 145509885543Smrg else if (attribute == xvContrast) 145609885543Smrg *value = pPort->Attribute[XV_CONTRAST]; 145709885543Smrg else if (attribute == xvSaturation) 145809885543Smrg *value = pPort->Attribute[XV_SATURATION]; 145909885543Smrg else if (attribute == xvHue) 146009885543Smrg *value = pPort->Attribute[XV_HUE]; 146109885543Smrg else if (attribute == xvColorKey) 146209885543Smrg *value = pPort->Attribute[XV_COLORKEY]; 146309885543Smrg else { 146409885543Smrg LEAVE_PROC("SMI_GetPortAttribute"); 146509885543Smrg return BadMatch; 146609885543Smrg } 146709885543Smrg 146809885543Smrg LEAVE_PROC("SMI_GetPortAttribute"); 146909885543Smrg return Success; 147009885543Smrg} 147109885543Smrg 147209885543Smrg 147309885543Smrgstatic void 147409885543SmrgSMI_QueryBestSize( 147509885543Smrg ScrnInfoPtr pScrn, 147609885543Smrg Bool motion, 147709885543Smrg short vid_w, 147809885543Smrg short vid_h, 147909885543Smrg short drw_w, 148009885543Smrg short drw_h, 148109885543Smrg unsigned int *p_w, 148209885543Smrg unsigned int *p_h, 148309885543Smrg pointer data 148409885543Smrg) 148509885543Smrg{ 148609885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 148709885543Smrg 148809885543Smrg ENTER_PROC("SMI_QueryBestSize"); 148909885543Smrg 149009885543Smrg *p_w = min(drw_w, pSmi->lcdWidth); 149109885543Smrg *p_h = min(drw_h, pSmi->lcdHeight); 149209885543Smrg 149309885543Smrg LEAVE_PROC("SMI_QueryBestSize"); 149409885543Smrg} 149509885543Smrg 149609885543Smrg 149709885543Smrgstatic int 149809885543SmrgSMI_PutImage( 149909885543Smrg ScrnInfoPtr pScrn, 150009885543Smrg short src_x, 150109885543Smrg short src_y, 150209885543Smrg short drw_x, 150309885543Smrg short drw_y, 150409885543Smrg short src_w, 150509885543Smrg short src_h, 150609885543Smrg short drw_w, 150709885543Smrg short drw_h, 150809885543Smrg int id, 150909885543Smrg unsigned char *buf, 151009885543Smrg short width, 151109885543Smrg short height, 151209885543Smrg Bool sync, 151309885543Smrg RegionPtr clipBoxes, 151409885543Smrg pointer data, 151509885543Smrg DrawablePtr pDraw 151609885543Smrg) 151709885543Smrg{ 151809885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 151909885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 152009885543Smrg INT32 x1, y1, x2, y2; 152109885543Smrg int bpp = 0; 152209885543Smrg int srcPitch, srcPitch2 = 0, dstPitch, size; 152309885543Smrg BoxRec dstBox; 152409885543Smrg CARD32 offset, offset2 = 0, offset3 = 0, tmp; 152509885543Smrg int left, top, nPixels, nLines; 152609885543Smrg unsigned char *dstStart; 152709885543Smrg 152809885543Smrg ENTER_PROC("SMI_PutImage"); 152909885543Smrg 153009885543Smrg x1 = src_x; 153109885543Smrg y1 = src_y; 153209885543Smrg x2 = src_x + src_w; 153309885543Smrg y2 = src_y + src_h; 153409885543Smrg 153509885543Smrg dstBox.x1 = drw_x; 153609885543Smrg dstBox.y1 = drw_y; 153709885543Smrg dstBox.x2 = drw_x + drw_w; 153809885543Smrg dstBox.y2 = drw_y + drw_h; 153909885543Smrg 154009885543Smrg if (!SMI_ClipVideo(pScrn, &dstBox, &x1, &y1, &x2, &y2, clipBoxes, width, height)) { 154109885543Smrg LEAVE_PROC("SMI_PutImage"); 154209885543Smrg return Success; 154309885543Smrg } 154409885543Smrg 154509885543Smrg dstBox.x1 -= pScrn->frameX0; 154609885543Smrg dstBox.y1 -= pScrn->frameY0; 154709885543Smrg dstBox.x2 -= pScrn->frameX0; 154809885543Smrg dstBox.y2 -= pScrn->frameY0; 154909885543Smrg 155009885543Smrg 155109885543Smrg switch (id) { 155209885543Smrg case FOURCC_YV12: 155309885543Smrg srcPitch = (width + 3) & ~3; 155409885543Smrg offset2 = srcPitch * height; 155509885543Smrg srcPitch2 = ((width >> 1) + 3) & ~3; 155609885543Smrg offset3 = offset2 + (srcPitch2 * (height >> 1)); 155709885543Smrg dstPitch = ((width << 1) + 15) & ~15; 155809885543Smrg break; 155909885543Smrg case FOURCC_I420: 156009885543Smrg srcPitch = (width + 3) & ~3; 156109885543Smrg offset3 = srcPitch * height; 156209885543Smrg srcPitch2 = ((width >> 1) + 3) & ~3; 156309885543Smrg offset2 = offset3 + (srcPitch2 * (height >> 1)); 156409885543Smrg dstPitch = ((width << 1) + 15) & ~15; 156509885543Smrg break; 156609885543Smrg case FOURCC_RV24: 156709885543Smrg bpp = 3; 156809885543Smrg srcPitch = width * bpp; 156909885543Smrg dstPitch = (srcPitch + 15) & ~15; 157009885543Smrg break; 157109885543Smrg case FOURCC_RV32: 157209885543Smrg bpp = 4; 157309885543Smrg srcPitch = width * bpp; 157409885543Smrg dstPitch = (srcPitch + 15) & ~15; 157509885543Smrg break; 157609885543Smrg case FOURCC_YUY2: 157709885543Smrg case FOURCC_RV15: 157809885543Smrg case FOURCC_RV16: 157909885543Smrg default: 158009885543Smrg bpp = 2; 158109885543Smrg srcPitch = width * bpp; 158209885543Smrg dstPitch = (srcPitch + 15) & ~15; 158309885543Smrg break; 158409885543Smrg } 158509885543Smrg 158609885543Smrg size = dstPitch * height; 158709885543Smrg pPort->video_offset = SMI_AllocateMemory(pScrn, &pPort->video_memory, size); 158809885543Smrg if (pPort->video_offset == 0) { 158909885543Smrg LEAVE_PROC("SMI_PutImage"); 159009885543Smrg return BadAlloc; 159109885543Smrg } 159209885543Smrg 159309885543Smrg top = y1 >> 16; 159409885543Smrg left = (x1 >> 16) & ~1; 159509885543Smrg nPixels = ((((x2 + 0xFFFF) >> 16) + 1) & ~1) - left; 159609885543Smrg left *= bpp; 159709885543Smrg 159809885543Smrg offset = pPort->video_offset + (top * dstPitch); 159909885543Smrg dstStart = pSmi->FBBase + offset + left; 160009885543Smrg 160109885543Smrg switch(id) { 160209885543Smrg case FOURCC_YV12: 160309885543Smrg case FOURCC_I420: 160409885543Smrg top &= ~1; 160509885543Smrg tmp = ((top >> 1) * srcPitch2) + (left >> 2); 160609885543Smrg offset2 += tmp; 160709885543Smrg offset3 += tmp; 160809885543Smrg if (id == FOURCC_I420) { 160909885543Smrg tmp = offset2; 161009885543Smrg offset2 = offset3; 161109885543Smrg offset3 = tmp; 161209885543Smrg } 161309885543Smrg nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 161409885543Smrg xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), 161509885543Smrg buf + offset2, buf + offset3, dstStart, 161609885543Smrg srcPitch, srcPitch2, dstPitch, nLines, nPixels); 161709885543Smrg break; 161809885543Smrg case FOURCC_UYVY: 161909885543Smrg case FOURCC_YUY2: 162009885543Smrg default: 162109885543Smrg buf += (top * srcPitch) + left; 162209885543Smrg nLines = ((y2 + 0xffff) >> 16) - top; 162309885543Smrg xf86XVCopyPacked(buf, dstStart, srcPitch, dstPitch, nLines, nPixels); 162409885543Smrg break; 162509885543Smrg } 162609885543Smrg 162709885543Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) 162809885543Smrg if (!RegionsEqual(&pPort->clip, clipBoxes)) 162909885543Smrg#else 163009885543Smrg if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) 163109885543Smrg#endif 163209885543Smrg { 163309885543Smrg REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); 163409885543Smrg xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], 163509885543Smrg clipBoxes); 163609885543Smrg } 163709885543Smrg 163809885543Smrg if (pSmi->Chipset != SMI_COUGAR3DR) 163909885543Smrg SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, 164009885543Smrg &dstBox, src_w, src_h, drw_w, drw_h); 164109885543Smrg else 164209885543Smrg SMI_DisplayVideo0730(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, 164309885543Smrg &dstBox, src_w, src_h, drw_w, drw_h); 164409885543Smrg 164509885543Smrg pPort->videoStatus = CLIENT_VIDEO_ON; 164609885543Smrg LEAVE_PROC("SMI_PutImage"); 164709885543Smrg return Success; 164809885543Smrg 164909885543Smrg} 165009885543Smrg 165109885543Smrg 165209885543Smrgstatic int 165309885543SmrgSMI_QueryImageAttributes( 165409885543Smrg ScrnInfoPtr pScrn, 165509885543Smrg int id, 165609885543Smrg unsigned short *width, 165709885543Smrg unsigned short *height, 165809885543Smrg int *pitches, 165909885543Smrg int *offsets 166009885543Smrg) 166109885543Smrg{ 166209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 166309885543Smrg int size, tmp; 166409885543Smrg 166509885543Smrg ENTER_PROC("SMI_QueryImageAttributes"); 166609885543Smrg 166709885543Smrg if (*width > pSmi->lcdWidth) { 166809885543Smrg *width = pSmi->lcdWidth; 166909885543Smrg } 167009885543Smrg if (*height > pSmi->lcdHeight) { 167109885543Smrg *height = pSmi->lcdHeight; 167209885543Smrg } 167309885543Smrg 167409885543Smrg *width = (*width + 1) & ~1; 167509885543Smrg if (offsets != NULL) { 167609885543Smrg offsets[0] = 0; 167709885543Smrg } 167809885543Smrg 167909885543Smrg switch (id) { 168009885543Smrg case FOURCC_YV12: 168109885543Smrg case FOURCC_I420: 168209885543Smrg *height = (*height + 1) & ~1; 168309885543Smrg size = (*width + 3) & ~3; 168409885543Smrg if (pitches != NULL) { 168509885543Smrg pitches[0] = size; 168609885543Smrg } 168709885543Smrg size *= *height; 168809885543Smrg if (offsets != NULL) { 168909885543Smrg offsets[1] = size; 169009885543Smrg } 169109885543Smrg tmp = ((*width >> 1) + 3) & ~3; 169209885543Smrg if (pitches != NULL) { 169309885543Smrg pitches[1] = pitches[2] = tmp; 169409885543Smrg } 169509885543Smrg tmp *= (*height >> 1); 169609885543Smrg size += tmp; 169709885543Smrg if (offsets != NULL) { 169809885543Smrg offsets[2] = size; 169909885543Smrg } 170009885543Smrg size += tmp; 170109885543Smrg break; 170209885543Smrg case FOURCC_YUY2: 170309885543Smrg case FOURCC_RV15: 170409885543Smrg case FOURCC_RV16: 170509885543Smrg default: 170609885543Smrg size = *width * 2; 170709885543Smrg if (pitches != NULL) { 170809885543Smrg pitches[0] = size; 170909885543Smrg } 171009885543Smrg size *= *height; 171109885543Smrg break; 171209885543Smrg case FOURCC_RV24: 171309885543Smrg size = *width * 3; 171409885543Smrg if (pitches != NULL) { 171509885543Smrg pitches[0] = size; 171609885543Smrg } 171709885543Smrg size *= *height; 171809885543Smrg break; 171909885543Smrg case FOURCC_RV32: 172009885543Smrg size = *width * 4; 172109885543Smrg if (pitches != NULL) { 172209885543Smrg pitches[0] = size; 172309885543Smrg } 172409885543Smrg size *= *height; 172509885543Smrg break; 172609885543Smrg } 172709885543Smrg 172809885543Smrg LEAVE_PROC("SMI_QueryImageAttributes"); 172909885543Smrg return size; 173009885543Smrg} 173109885543Smrg 173209885543Smrg 173309885543Smrg/******************************************************************************\ 173409885543Smrg** ** 173509885543Smrg** S U P P O R T F U N C T I O N S ** 173609885543Smrg** ** 173709885543Smrg\******************************************************************************/ 173809885543Smrg#if 0 173909885543Smrgstatic void 174009885543SmrgSMI_WaitForSync( 174109885543Smrg ScrnInfoPtr pScrn 174209885543Smrg) 174309885543Smrg{ 174409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 174509885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 174609885543Smrg int vgaIOBase = hwp->IOBase; 174709885543Smrg int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 174809885543Smrg int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 174909885543Smrg 175009885543Smrg VerticalRetraceWait(); 175109885543Smrg} 175209885543Smrg#endif 175309885543Smrg 175409885543Smrgstatic Bool 175509885543SmrgSMI_ClipVideo( 175609885543Smrg ScrnInfoPtr pScrn, 175709885543Smrg BoxPtr dst, 175809885543Smrg INT32 *x1, 175909885543Smrg INT32 *y1, 176009885543Smrg INT32 *x2, 176109885543Smrg INT32 *y2, 176209885543Smrg RegionPtr reg, 176309885543Smrg INT32 width, 176409885543Smrg INT32 height 176509885543Smrg) 176609885543Smrg{ 176709885543Smrg ScreenPtr pScreen = pScrn->pScreen; 176809885543Smrg INT32 vscale, hscale; 176909885543Smrg BoxPtr extents = REGION_EXTENTS(pScreen, reg); 177009885543Smrg int diff; 177109885543Smrg 177209885543Smrg ENTER_PROC("SMI_ClipVideo"); 177309885543Smrg 177409885543Smrg DEBUG((VERBLEV, "ClipVideo(%d): x1=%d y1=%d x2=%d y2=%d\n", __LINE__, *x1 >> 16, *y1 >> 16, *x2 >> 16, *y2 >> 16)); 177509885543Smrg /* PDR#941 */ 177609885543Smrg extents->x1 = max(extents->x1, pScrn->frameX0); 177709885543Smrg extents->y1 = max(extents->y1, pScrn->frameY0); 177809885543Smrg 177909885543Smrg hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); 178009885543Smrg vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); 178109885543Smrg 178209885543Smrg *x1 <<= 16; *y1 <<= 16; 178309885543Smrg *x2 <<= 16; *y2 <<= 16; 178409885543Smrg 178509885543Smrg DEBUG((VERBLEV, "ClipVideo(%d): x1=%d y1=%d x2=%d y2=%d\n", __LINE__, *x1 >> 16, *y1 >> 16, *x2 >> 16, *y2 >> 16)); 178609885543Smrg 178709885543Smrg diff = extents->x1 - dst->x1; 178809885543Smrg if (diff > 0) { 178909885543Smrg dst->x1 = extents->x1; 179009885543Smrg *x1 += diff * hscale; 179109885543Smrg } 179209885543Smrg 179309885543Smrg diff = extents->y1 - dst->y1; 179409885543Smrg if (diff > 0) { 179509885543Smrg dst->y1 = extents->y1; 179609885543Smrg *y1 += diff * vscale; 179709885543Smrg } 179809885543Smrg 179909885543Smrg diff = dst->x2 - extents->x2; 180009885543Smrg if (diff > 0) { 180109885543Smrg dst->x2 = extents->x2; /* PDR#687 */ 180209885543Smrg *x2 -= diff * hscale; 180309885543Smrg } 180409885543Smrg 180509885543Smrg diff = dst->y2 - extents->y2; 180609885543Smrg if (diff > 0) { 180709885543Smrg dst->y2 = extents->y2; 180809885543Smrg *y2 -= diff * vscale; 180909885543Smrg } 181009885543Smrg 181109885543Smrg DEBUG((VERBLEV, "ClipVideo(%d): x1=%d y1=%d x2=%d y2=%d\n", __LINE__, *x1 >> 16, *y1 >> 16, *x2 >> 16, *y2 >> 16)); 181209885543Smrg 181309885543Smrg if (*x1 < 0) { 181409885543Smrg diff = (-*x1 + hscale - 1) / hscale; 181509885543Smrg dst->x1 += diff; 181609885543Smrg *x1 += diff * hscale; 181709885543Smrg } 181809885543Smrg 181909885543Smrg if (*y1 < 0) { 182009885543Smrg diff = (-*y1 + vscale - 1) / vscale; 182109885543Smrg dst->y1 += diff; 182209885543Smrg *y1 += diff * vscale; 182309885543Smrg } 182409885543Smrg 182509885543Smrg DEBUG((VERBLEV, "ClipVideo(%d): x1=%d y1=%d x2=%d y2=%d\n", __LINE__, *x1 >> 16, *y1 >> 16, *x2 >> 16, *y2 >> 16)); 182609885543Smrg 182709885543Smrg#if 0 /* aaa was macht dieser code? */ 182809885543Smrg delta = *x2 - (width << 16); 182909885543Smrg if (delta > 0) 183009885543Smrg { 183109885543Smrg diff = (delta + hscale - 1) / hscale; 183209885543Smrg dst->x2 -= diff; 183309885543Smrg *x2 -= diff * hscale; 183409885543Smrg } 183509885543Smrg 183609885543Smrg delta = *y2 - (height << 16); 183709885543Smrg if (delta > 0) 183809885543Smrg { 183909885543Smrg diff = (delta + vscale - 1) / vscale; 184009885543Smrg dst->y2 -= diff; 184109885543Smrg *y2 -= diff * vscale; 184209885543Smrg } 184309885543Smrg#endif 184409885543Smrg 184509885543Smrg DEBUG((VERBLEV, "ClipVideo(%d): x1=%d y1=%d x2=%d y2=%d\n", __LINE__, *x1 >> 16, *y1 >> 16, *x2 >> 16, *y2 >> 16)); 184609885543Smrg 184709885543Smrg if ((*x1 >= *x2) || (*y1 >= *y2)) { 184809885543Smrg LEAVE_PROC("SMI_ClipVideo"); 184909885543Smrg return FALSE; 185009885543Smrg } 185109885543Smrg 185209885543Smrg if ((dst->x1 != extents->x1) || (dst->y1 != extents->y1) || 185309885543Smrg (dst->x2 != extents->x2) || (dst->y2 != extents->y2)) { 185409885543Smrg RegionRec clipReg; 185509885543Smrg REGION_INIT(pScreen, &clipReg, dst, 1); 185609885543Smrg REGION_INTERSECT(pScreen, reg, reg, &clipReg); 185709885543Smrg REGION_UNINIT(pScreen, &clipReg); 185809885543Smrg } 185909885543Smrg 186009885543Smrg DEBUG((VERBLEV, "ClipVideo(%d): x1=%d y1=%d x2=%d y2=%d\n", __LINE__, *x1 >> 16, *y1 >> 16, *x2 >> 16, *y2 >> 16)); 186109885543Smrg 186209885543Smrg LEAVE_PROC("SMI_ClipVideo"); 186309885543Smrg return TRUE; 186409885543Smrg} 186509885543Smrg 186609885543Smrgstatic void 186709885543SmrgSMI_DisplayVideo( 186809885543Smrg ScrnInfoPtr pScrn, 186909885543Smrg int id, 187009885543Smrg int offset, 187109885543Smrg short width, 187209885543Smrg short height, 187309885543Smrg int pitch, 187409885543Smrg int x1, 187509885543Smrg int y1, 187609885543Smrg int x2, 187709885543Smrg int y2, 187809885543Smrg BoxPtr dstBox, 187909885543Smrg short vid_w, 188009885543Smrg short vid_h, 188109885543Smrg short drw_w, 188209885543Smrg short drw_h 188309885543Smrg) 188409885543Smrg{ 188509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 188609885543Smrg CARD32 vpr00; 188709885543Smrg int hstretch, vstretch; 188809885543Smrg 188909885543Smrg ENTER_PROC("SMI_DisplayVideo"); 189009885543Smrg 189109885543Smrg vpr00 = READ_VPR(pSmi, 0x00) & ~0x0CB800FF; 189209885543Smrg 189309885543Smrg switch (id) { 189409885543Smrg case FOURCC_YV12: 189509885543Smrg case FOURCC_I420: 189609885543Smrg case FOURCC_YUY2: 189709885543Smrg vpr00 |= 0x6; 189809885543Smrg break; 189909885543Smrg case FOURCC_RV15: 190009885543Smrg vpr00 |= 0x1; 190109885543Smrg break; 190209885543Smrg case FOURCC_RV16: 190309885543Smrg vpr00 |= 0x2; 190409885543Smrg break; 190509885543Smrg case FOURCC_RV24: 190609885543Smrg vpr00 |= 0x4; 190709885543Smrg break; 190809885543Smrg case FOURCC_RV32: 190909885543Smrg vpr00 |= 0x3; 191009885543Smrg break; 191109885543Smrg } 191209885543Smrg 191309885543Smrg if (drw_w > vid_w) { 191409885543Smrg hstretch = (2560 * vid_w / drw_w + 5) / 10; 191509885543Smrg } else { 191609885543Smrg hstretch = 0; 191709885543Smrg } 191809885543Smrg 191909885543Smrg if (drw_h > vid_h) { 192009885543Smrg vstretch = (2560 * vid_h / drw_h + 5) / 10; 192109885543Smrg vpr00 |= 1 << 21; 192209885543Smrg } else { 192309885543Smrg vstretch = 0; 192409885543Smrg } 192509885543Smrg#if 0 192609885543Smrg SMI_WaitForSync(pScrn); 192709885543Smrg#endif 192809885543Smrg WRITE_VPR(pSmi, 0x00, vpr00 | (1 << 3) | (1 << 20)); 192909885543Smrg WRITE_VPR(pSmi, 0x14, (dstBox->x1) | (dstBox->y1 << 16)); 193009885543Smrg WRITE_VPR(pSmi, 0x18, (dstBox->x2) | (dstBox->y2 << 16)); 193109885543Smrg WRITE_VPR(pSmi, 0x1C, offset >> 3); 193209885543Smrg WRITE_VPR(pSmi, 0x20, (pitch >> 3) | ((pitch >> 3) << 16)); 193309885543Smrg WRITE_VPR(pSmi, 0x24, (hstretch << 8) | vstretch); 193409885543Smrg 193509885543Smrg LEAVE_PROC("SMI_DisplayVideo"); 193609885543Smrg} 193709885543Smrg 193809885543Smrgstatic void 193909885543SmrgSMI_DisplayVideo0730( 194009885543Smrg ScrnInfoPtr pScrn, 194109885543Smrg int id, 194209885543Smrg int offset, 194309885543Smrg short width, 194409885543Smrg short height, 194509885543Smrg int pitch, 194609885543Smrg int x1, 194709885543Smrg int y1, 194809885543Smrg int x2, 194909885543Smrg int y2, 195009885543Smrg BoxPtr dstBox, 195109885543Smrg short vid_w, 195209885543Smrg short vid_h, 195309885543Smrg short drw_w, 195409885543Smrg short drw_h 195509885543Smrg) 195609885543Smrg{ 195709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 195809885543Smrg CARD32 fpr00; 195909885543Smrg int hstretch, vstretch; 196009885543Smrg 196109885543Smrg ENTER_PROC("SMI_DisplayVideo0730"); 196209885543Smrg 196309885543Smrg fpr00 = READ_FPR(pSmi, 0x00) & ~(FPR00_MASKBITS); 196409885543Smrg 196509885543Smrg switch (id) { 196609885543Smrg case FOURCC_YV12: 196709885543Smrg case FOURCC_I420: 196809885543Smrg case FOURCC_YUY2: 196909885543Smrg fpr00 |= FPR00_FMT_YUV422; 197009885543Smrg break; 197109885543Smrg case FOURCC_RV15: 197209885543Smrg fpr00 |= FPR00_FMT_15P; 197309885543Smrg break; 197409885543Smrg case FOURCC_RV16: 197509885543Smrg fpr00 |= FPR00_FMT_16P; 197609885543Smrg break; 197709885543Smrg case FOURCC_RV24: 197809885543Smrg fpr00 |= FPR00_FMT_24P; 197909885543Smrg break; 198009885543Smrg case FOURCC_RV32: 198109885543Smrg fpr00 |= FPR00_FMT_32P; 198209885543Smrg break; 198309885543Smrg } 198409885543Smrg 198509885543Smrg /* the formulas for calculating the stretch values do not match the 198609885543Smrg documentation, but they're the same as the ddraw driver and they work */ 198709885543Smrg if (drw_w > vid_w) { 198809885543Smrg hstretch = (8192 * vid_w / drw_w); 198909885543Smrg } else { 199009885543Smrg hstretch = 0; 199109885543Smrg } 199209885543Smrg 199309885543Smrg if (drw_h > vid_h) { 199409885543Smrg vstretch = (8192 * vid_h / drw_h); 199509885543Smrg } else { 199609885543Smrg vstretch = 0; 199709885543Smrg } 199809885543Smrg 199909885543Smrg WRITE_FPR(pSmi, FPR00, fpr00 | FPR00_VWIENABLE | FPR00_VWIKEYENABLE); 200009885543Smrg WRITE_FPR(pSmi, FPR14, (dstBox->x1) | (dstBox->y1 << 16)); 200109885543Smrg WRITE_FPR(pSmi, FPR18, (dstBox->x2) | (dstBox->y2 << 16)); 200209885543Smrg WRITE_FPR(pSmi, FPR1C, offset >> 3); 200309885543Smrg WRITE_FPR(pSmi, FPR20, (pitch >> 3) | ((pitch >> 3) << 16)); 200409885543Smrg WRITE_FPR(pSmi, FPR24, (hstretch & 0xFF00) | ((vstretch & 0xFF00)>>8)); 200509885543Smrg WRITE_FPR(pSmi, FPR68, ((hstretch & 0x00FF)<<8) | (vstretch & 0x00FF)); 200609885543Smrg 200709885543Smrg LEAVE_PROC("SMI_DisplayVideo0730"); 200809885543Smrg} 200909885543Smrg 201009885543Smrgstatic void 201109885543SmrgSMI_BlockHandler( 201209885543Smrg int i, 201309885543Smrg pointer blockData, 201409885543Smrg pointer pTimeout, 201509885543Smrg pointer pReadMask 201609885543Smrg) 201709885543Smrg{ 201809885543Smrg ScreenPtr pScreen = screenInfo.screens[i]; 201909885543Smrg ScrnInfoPtr pScrn = xf86Screens[i]; 202009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 202109885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 202209885543Smrg 202309885543Smrg pScreen->BlockHandler = pSmi->BlockHandler; 202409885543Smrg (*pScreen->BlockHandler)(i, blockData, pTimeout, pReadMask); 202509885543Smrg pScreen->BlockHandler = SMI_BlockHandler; 202609885543Smrg 202709885543Smrg if (pPort->videoStatus & TIMER_MASK) { 202809885543Smrg UpdateCurrentTime(); 202909885543Smrg if (pPort->videoStatus & OFF_TIMER) { 203009885543Smrg if (pPort->offTime < currentTime.milliseconds) { 203109885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 203209885543Smrg WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); 203309885543Smrg } else { 203409885543Smrg WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); 203509885543Smrg } 203609885543Smrg pPort->videoStatus = FREE_TIMER; 203709885543Smrg pPort->freeTime = currentTime.milliseconds + FREE_DELAY; 203809885543Smrg } 203909885543Smrg } else { 204009885543Smrg if (pPort->freeTime < currentTime.milliseconds) { 204109885543Smrg SMI_FreeMemory(pScrn, pPort->video_memory); 204209885543Smrg pPort->video_memory = NULL; 204309885543Smrg } 204409885543Smrg pPort->videoStatus = 0; 204509885543Smrg } 204609885543Smrg } 204709885543Smrg} 204809885543Smrg 204909885543Smrg#if 0 205009885543Smrgstatic int 205109885543SmrgSMI_SendI2C( 205209885543Smrg ScrnInfoPtr pScrn, 205309885543Smrg CARD8 device, 205409885543Smrg char *devName, 205509885543Smrg SMI_I2CDataPtr i2cData 205609885543Smrg) 205709885543Smrg{ 205809885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 205909885543Smrg I2CDevPtr dev; 206009885543Smrg int status = Success; 206109885543Smrg 206209885543Smrg ENTER_PROC("SMI_SendI2C"); 206309885543Smrg 206409885543Smrg if (pSmi->I2C == NULL) 206509885543Smrg { 206609885543Smrg LEAVE_PROC("SMI_SendI2C"); 206709885543Smrg return(BadAlloc); 206809885543Smrg } 206909885543Smrg 207009885543Smrg dev = xf86CreateI2CDevRec(); 207109885543Smrg if (dev == NULL) 207209885543Smrg { 207309885543Smrg LEAVE_PROC("SMI_SendI2C"); 207409885543Smrg return(BadAlloc); 207509885543Smrg } 207609885543Smrg dev->DevName = devName; 207709885543Smrg dev->SlaveAddr = device; 207809885543Smrg dev->pI2CBus = pSmi->I2C; 207909885543Smrg 208009885543Smrg if (!xf86I2CDevInit(dev)) 208109885543Smrg { 208209885543Smrg status = BadAlloc; 208309885543Smrg } 208409885543Smrg else 208509885543Smrg { 208609885543Smrg while (i2cData->address != 0xFF || i2cData->data != 0xFF) /* PDR#676 */ 208709885543Smrg { 208809885543Smrg if (!xf86I2CWriteByte(dev, i2cData->address, i2cData->data)) 208909885543Smrg { 209009885543Smrg status = BadAlloc; 209109885543Smrg break; 209209885543Smrg } 209309885543Smrg i2cData++; 209409885543Smrg } 209509885543Smrg } 209609885543Smrg 209709885543Smrg xf86DestroyI2CDevRec(dev, TRUE); 209809885543Smrg LEAVE_PROC("SMI_SendI2C"); 209909885543Smrg return(status); 210009885543Smrg} 210109885543Smrg#endif 210209885543Smrg 210309885543Smrg/******************************************************************************\ 210409885543Smrg** ** 210509885543Smrg** O F F S C R E E N M E M O R Y M A N A G E R ** 210609885543Smrg** ** 210709885543Smrg\******************************************************************************/ 210809885543Smrg 210909885543Smrgstatic void 211009885543SmrgSMI_InitOffscreenImages( 211109885543Smrg ScreenPtr pScreen 211209885543Smrg) 211309885543Smrg{ 211409885543Smrg XF86OffscreenImagePtr offscreenImages; 211509885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 211609885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 211709885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 211809885543Smrg 211909885543Smrg ENTER_PROC("SMI_InitOffscreenImages"); 212009885543Smrg 212109885543Smrg offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)); 212209885543Smrg if (offscreenImages == NULL) { 212309885543Smrg LEAVE_PROC("SMI_InitOffscreenImages"); 212409885543Smrg return; 212509885543Smrg } 212609885543Smrg 212709885543Smrg offscreenImages->image = SMI_VideoImages; 212809885543Smrg offscreenImages->flags = VIDEO_OVERLAID_IMAGES 212909885543Smrg | VIDEO_CLIP_TO_VIEWPORT; 213009885543Smrg offscreenImages->alloc_surface = SMI_AllocSurface; 213109885543Smrg offscreenImages->free_surface = SMI_FreeSurface; 213209885543Smrg offscreenImages->display = SMI_DisplaySurface; 213309885543Smrg offscreenImages->stop = SMI_StopSurface; 213409885543Smrg offscreenImages->getAttribute = SMI_GetSurfaceAttribute; 213509885543Smrg offscreenImages->setAttribute = SMI_SetSurfaceAttribute; 213609885543Smrg offscreenImages->max_width = pSmi->lcdWidth; 213709885543Smrg offscreenImages->max_height = pSmi->lcdHeight; 213809885543Smrg if (!pPort->I2CDev.SlaveAddr) { 213909885543Smrg offscreenImages->num_attributes = nElems(SMI_VideoAttributes); 214009885543Smrg offscreenImages->attributes = SMI_VideoAttributes; 214109885543Smrg } else { 214209885543Smrg offscreenImages->num_attributes = nElems(SMI_VideoAttributesSAA711x); 214309885543Smrg offscreenImages->attributes = SMI_VideoAttributesSAA711x; 214409885543Smrg } 214509885543Smrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 214609885543Smrg 214709885543Smrg LEAVE_PROC("SMI_InitOffscreenImages"); 214809885543Smrg} 214909885543Smrg 215009885543Smrgstatic void 215109885543SmrgSMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) 215209885543Smrg{ 215309885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 215409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 215509885543Smrg SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr; 215609885543Smrg 215709885543Smrg ENTER_PROC("SMI_VideoSave"); 215809885543Smrg 215909885543Smrg if (pPort->video_memory == area) 216009885543Smrg pPort->video_memory = NULL; 216109885543Smrg 216209885543Smrg LEAVE_PROC("SMI_VideoSave"); 216309885543Smrg} 216409885543Smrg 216509885543Smrgstatic CARD32 216609885543SmrgSMI_AllocateMemory( 216709885543Smrg ScrnInfoPtr pScrn, 216809885543Smrg void **mem_struct, 216909885543Smrg int size 217009885543Smrg) 217109885543Smrg{ 217209885543Smrg ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; 217309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 217409885543Smrg int offset = 0; 217509885543Smrg 217609885543Smrg ENTER_PROC("SMI_AllocateMemory"); 217709885543Smrg 217809885543Smrg if (pSmi->useEXA) { 217909885543Smrg ExaOffscreenArea *area = *mem_struct; 218009885543Smrg 218109885543Smrg if (area != NULL) { 218209885543Smrg if (area->size >= size) 218309885543Smrg return area->offset; 218409885543Smrg 218509885543Smrg exaOffscreenFree(pScrn->pScreen, area); 218609885543Smrg } 218709885543Smrg 218809885543Smrg area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, SMI_VideoSave, NULL); 218909885543Smrg 219009885543Smrg *mem_struct = area; 219109885543Smrg if (area == NULL) 219209885543Smrg return 0; 219309885543Smrg offset = area->offset; 219409885543Smrg } else { 219509885543Smrg FBLinearPtr linear = *mem_struct; 219609885543Smrg 219709885543Smrg /* XAA allocates in units of pixels at the screen bpp, 219809885543Smrg * so adjust size appropriately. 219909885543Smrg */ 220009885543Smrg size = (size + pSmi->Bpp - 1) / pSmi->Bpp; 220109885543Smrg 220209885543Smrg if (linear) { 220309885543Smrg if (linear->size >= size) 220409885543Smrg return linear->offset * pSmi->Bpp; 220509885543Smrg 220609885543Smrg if (xf86ResizeOffscreenLinear(linear, size)) 220709885543Smrg return linear->offset * pSmi->Bpp; 220809885543Smrg 220909885543Smrg xf86FreeOffscreenLinear(linear); 221009885543Smrg } 221109885543Smrg 221209885543Smrg linear = xf86AllocateOffscreenLinear(pScreen, size, 16, NULL, NULL, NULL); 221309885543Smrg *mem_struct = linear; 221409885543Smrg 221509885543Smrg if (!linear) { 221609885543Smrg int max_size; 221709885543Smrg 221809885543Smrg xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, PRIORITY_EXTREME); 221909885543Smrg if (max_size < size) 222009885543Smrg return 0; 222109885543Smrg 222209885543Smrg xf86PurgeUnlockedOffscreenAreas(pScreen); 222309885543Smrg 222409885543Smrg linear = xf86AllocateOffscreenLinear(pScreen, size, 16, NULL, NULL, NULL); 222509885543Smrg *mem_struct = linear; 222609885543Smrg 222709885543Smrg if (!linear) 222809885543Smrg return 0; 222909885543Smrg } 223009885543Smrg 223109885543Smrg DEBUG((VERBLEV, "offset = %p\n", offset)); 223209885543Smrg } 223309885543Smrg 223409885543Smrg DEBUG((VERBLEV, "area = %p\n", area)); 223509885543Smrg LEAVE_PROC("SMI_AllocateMemory"); 223609885543Smrg return offset; 223709885543Smrg} 223809885543Smrg 223909885543Smrgstatic void 224009885543SmrgSMI_FreeMemory( 224109885543Smrg ScrnInfoPtr pScrn, 224209885543Smrg void *mem_struct 224309885543Smrg) 224409885543Smrg{ 224509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 224609885543Smrg 224709885543Smrg ENTER_PROC("SMI_FreeMemory"); 224809885543Smrg 224909885543Smrg if (pSmi->useEXA) { 225009885543Smrg ExaOffscreenArea *area = mem_struct; 225109885543Smrg 225209885543Smrg if (area != NULL) 225309885543Smrg exaOffscreenFree(pScrn->pScreen, area); 225409885543Smrg } else { 225509885543Smrg FBLinearPtr linear = mem_struct; 225609885543Smrg 225709885543Smrg if (linear != NULL) 225809885543Smrg xf86FreeOffscreenLinear(linear); 225909885543Smrg } 226009885543Smrg 226109885543Smrg LEAVE_PROC("SMI_FreeMemory"); 226209885543Smrg} 226309885543Smrg 226409885543Smrgstatic int 226509885543SmrgSMI_AllocSurface( 226609885543Smrg ScrnInfoPtr pScrn, 226709885543Smrg int id, 226809885543Smrg unsigned short width, 226909885543Smrg unsigned short height, 227009885543Smrg XF86SurfacePtr surface 227109885543Smrg) 227209885543Smrg{ 227309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 227409885543Smrg int pitch, bpp, offset, size; 227509885543Smrg void *surface_memory = NULL; 227609885543Smrg SMI_OffscreenPtr ptrOffscreen; 227709885543Smrg 227809885543Smrg ENTER_PROC("SMI_AllocSurface"); 227909885543Smrg 228009885543Smrg if ((width > pSmi->lcdWidth) || (height > pSmi->lcdHeight)) { 228109885543Smrg LEAVE_PROC("SMI_AllocSurface"); 228209885543Smrg return BadAlloc; 228309885543Smrg } 228409885543Smrg 228509885543Smrg switch (id) { 228609885543Smrg case FOURCC_YV12: 228709885543Smrg case FOURCC_I420: 228809885543Smrg case FOURCC_YUY2: 228909885543Smrg case FOURCC_RV15: 229009885543Smrg case FOURCC_RV16: 229109885543Smrg bpp = 2; 229209885543Smrg break; 229309885543Smrg case FOURCC_RV24: 229409885543Smrg bpp = 3; 229509885543Smrg break; 229609885543Smrg case FOURCC_RV32: 229709885543Smrg bpp = 4; 229809885543Smrg break; 229909885543Smrg default: 230009885543Smrg LEAVE_PROC("SMI_AllocSurface"); 230109885543Smrg return BadAlloc; 230209885543Smrg } 230309885543Smrg 230409885543Smrg width = (width + 1) & ~1; 230509885543Smrg pitch = (width * bpp + 15) & ~15; 230609885543Smrg size = pitch * height; 230709885543Smrg 230809885543Smrg offset = SMI_AllocateMemory(pScrn, &surface_memory, size); 230909885543Smrg if (offset == 0) { 231009885543Smrg LEAVE_PROC("SMI_AllocSurface"); 231109885543Smrg return BadAlloc; 231209885543Smrg } 231309885543Smrg 231409885543Smrg surface->pitches = xalloc(sizeof(int)); 231509885543Smrg if (surface->pitches == NULL) { 231609885543Smrg SMI_FreeMemory(pScrn, surface_memory); 231709885543Smrg LEAVE_PROC("SMI_AllocSurface"); 231809885543Smrg return BadAlloc; 231909885543Smrg } 232009885543Smrg surface->offsets = xalloc(sizeof(int)); 232109885543Smrg if (surface->offsets == NULL) { 232209885543Smrg xfree(surface->pitches); 232309885543Smrg SMI_FreeMemory(pScrn, surface_memory); 232409885543Smrg LEAVE_PROC("SMI_AllocSurface"); 232509885543Smrg return BadAlloc; 232609885543Smrg } 232709885543Smrg 232809885543Smrg ptrOffscreen = xalloc(sizeof(SMI_OffscreenRec)); 232909885543Smrg if (ptrOffscreen == NULL) { 233009885543Smrg xfree(surface->offsets); 233109885543Smrg xfree(surface->pitches); 233209885543Smrg SMI_FreeMemory(pScrn, surface_memory); 233309885543Smrg LEAVE_PROC("SMI_AllocSurface"); 233409885543Smrg return BadAlloc; 233509885543Smrg } 233609885543Smrg 233709885543Smrg surface->pScrn = pScrn; 233809885543Smrg surface->id = id; 233909885543Smrg surface->width = width; 234009885543Smrg surface->height = height; 234109885543Smrg surface->pitches[0] = pitch; 234209885543Smrg surface->offsets[0] = offset; 234309885543Smrg surface->devPrivate.ptr = (pointer) ptrOffscreen; 234409885543Smrg 234509885543Smrg ptrOffscreen->surface_memory = surface_memory; 234609885543Smrg ptrOffscreen->isOn = FALSE; 234709885543Smrg 234809885543Smrg LEAVE_PROC("SMI_AllocSurface"); 234909885543Smrg return Success; 235009885543Smrg} 235109885543Smrg 235209885543Smrgstatic int 235309885543SmrgSMI_FreeSurface( 235409885543Smrg XF86SurfacePtr surface 235509885543Smrg) 235609885543Smrg{ 235709885543Smrg ScrnInfoPtr pScrn = surface->pScrn; 235809885543Smrg SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr; 235909885543Smrg 236009885543Smrg ENTER_PROC("SMI_FreeSurface"); 236109885543Smrg 236209885543Smrg if (ptrOffscreen->isOn) { 236309885543Smrg SMI_StopSurface(surface); 236409885543Smrg } 236509885543Smrg 236609885543Smrg SMI_FreeMemory(pScrn, ptrOffscreen->surface_memory); 236709885543Smrg xfree(surface->pitches); 236809885543Smrg xfree(surface->offsets); 236909885543Smrg xfree(surface->devPrivate.ptr); 237009885543Smrg 237109885543Smrg LEAVE_PROC("SMI_FreeSurface"); 237209885543Smrg return Success; 237309885543Smrg} 237409885543Smrg 237509885543Smrgstatic int 237609885543SmrgSMI_DisplaySurface( 237709885543Smrg XF86SurfacePtr surface, 237809885543Smrg short vid_x, 237909885543Smrg short vid_y, 238009885543Smrg short drw_x, 238109885543Smrg short drw_y, 238209885543Smrg short vid_w, 238309885543Smrg short vid_h, 238409885543Smrg short drw_w, 238509885543Smrg short drw_h, 238609885543Smrg RegionPtr clipBoxes 238709885543Smrg) 238809885543Smrg{ 238909885543Smrg SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr; 239009885543Smrg SMIPtr pSmi = SMIPTR(surface->pScrn); 239109885543Smrg SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr; 239209885543Smrg INT32 x1, y1, x2, y2; 239309885543Smrg BoxRec dstBox; 239409885543Smrg 239509885543Smrg ENTER_PROC("SMI_DisplaySurface"); 239609885543Smrg 239709885543Smrg x1 = vid_x; 239809885543Smrg x2 = vid_x + vid_w; 239909885543Smrg y1 = vid_y; 240009885543Smrg y2 = vid_y + vid_h; 240109885543Smrg 240209885543Smrg dstBox.x1 = drw_x; 240309885543Smrg dstBox.x2 = drw_x + drw_w; 240409885543Smrg dstBox.y1 = drw_y; 240509885543Smrg dstBox.y2 = drw_y + drw_h; 240609885543Smrg 240709885543Smrg if (!SMI_ClipVideo(surface->pScrn, &dstBox, &x1, &y1, &x2, &y2, clipBoxes, 240809885543Smrg surface->width, surface->height)) { 240909885543Smrg LEAVE_PROC("SMI_DisplaySurface"); 241009885543Smrg return Success; 241109885543Smrg } 241209885543Smrg 241309885543Smrg dstBox.x1 -= surface->pScrn->frameX0; 241409885543Smrg dstBox.y1 -= surface->pScrn->frameY0; 241509885543Smrg dstBox.x2 -= surface->pScrn->frameX0; 241609885543Smrg dstBox.y2 -= surface->pScrn->frameY0; 241709885543Smrg 241809885543Smrg xf86XVFillKeyHelper(surface->pScrn->pScreen, 241909885543Smrg pPort->Attribute[XV_COLORKEY], clipBoxes); 242009885543Smrg 242109885543Smrg if (pSmi->Chipset != SMI_COUGAR3DR) { 242209885543Smrg SMI_ResetVideo(surface->pScrn); 242309885543Smrg SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0], 242409885543Smrg surface->width, surface->height, surface->pitches[0], x1, y1, x2, 242509885543Smrg y2, &dstBox, vid_w, vid_h, drw_w, drw_h); 242609885543Smrg } else { 242709885543Smrg SMI_ResetVideo(surface->pScrn); 242809885543Smrg SMI_DisplayVideo0730(surface->pScrn, surface->id, surface->offsets[0], 242909885543Smrg surface->width, surface->height, surface->pitches[0], x1, y1, x2, 243009885543Smrg y2, &dstBox, vid_w, vid_h, drw_w, drw_h); 243109885543Smrg } 243209885543Smrg 243309885543Smrg ptrOffscreen->isOn = TRUE; 243409885543Smrg if (pPort->videoStatus & CLIENT_VIDEO_ON) { 243509885543Smrg REGION_EMPTY(surface->pScrn->pScreen, &pPort->clip); 243609885543Smrg UpdateCurrentTime(); 243709885543Smrg pPort->videoStatus = FREE_TIMER; 243809885543Smrg pPort->freeTime = currentTime.milliseconds + FREE_DELAY; 243909885543Smrg } 244009885543Smrg 244109885543Smrg LEAVE_PROC("SMI_DisplaySurface"); 244209885543Smrg return Success; 244309885543Smrg} 244409885543Smrg 244509885543Smrgstatic int 244609885543SmrgSMI_StopSurface( 244709885543Smrg XF86SurfacePtr surface 244809885543Smrg) 244909885543Smrg{ 245009885543Smrg SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr; 245109885543Smrg 245209885543Smrg ENTER_PROC("SMI_StopSurface"); 245309885543Smrg 245409885543Smrg if (ptrOffscreen->isOn) { 245509885543Smrg SMIPtr pSmi = SMIPTR(surface->pScrn); 245609885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 245709885543Smrg WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); 245809885543Smrg } else { 245909885543Smrg WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); 246009885543Smrg } 246109885543Smrg 246209885543Smrg ptrOffscreen->isOn = FALSE; 246309885543Smrg } 246409885543Smrg 246509885543Smrg LEAVE_PROC("SMI_StopSurface"); 246609885543Smrg return Success; 246709885543Smrg} 246809885543Smrg 246909885543Smrgstatic int 247009885543SmrgSMI_GetSurfaceAttribute( 247109885543Smrg ScrnInfoPtr pScrn, 247209885543Smrg Atom attr, 247309885543Smrg INT32 *value 247409885543Smrg) 247509885543Smrg{ 247609885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 247709885543Smrg 247809885543Smrg return SMI_GetPortAttribute(pScrn, attr, value, 247909885543Smrg (pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr); 248009885543Smrg} 248109885543Smrg 248209885543Smrgstatic int 248309885543SmrgSMI_SetSurfaceAttribute( 248409885543Smrg ScrnInfoPtr pScrn, 248509885543Smrg Atom attr, 248609885543Smrg INT32 value 248709885543Smrg) 248809885543Smrg{ 248909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 249009885543Smrg 249109885543Smrg return SMI_SetPortAttribute(pScrn, attr, value, 249209885543Smrg (pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr); 249309885543Smrg} 249409885543Smrg 249509885543Smrgstatic void 249609885543SmrgSetKeyReg(SMIPtr pSmi, int reg, int value) 249709885543Smrg{ 249809885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 249909885543Smrg WRITE_FPR(pSmi, reg, value); 250009885543Smrg } else { 250109885543Smrg WRITE_VPR(pSmi, reg, value); 250209885543Smrg } 250309885543Smrg} 250409885543Smrg 250509885543Smrg#else /* SMI_USE_VIDEO */ 250609885543Smrgvoid SMI_InitVideo(ScreenPtr pScreen) {} 250709885543Smrg#endif 2508