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