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 { 185beef1b22Smrg const 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 { 201beef1b22Smrg const 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{ 512beef1b22Smrg const char* norm_string; 513beef1b22Smrg const char* input_string; 51409885543Smrg char channel_string[20]; 515beef1b22Smrg char* name_string; 51609885543Smrg 5177104f784Smrg ENTER(); 51809885543Smrg 51909885543Smrg norm_string = VideoNorms[norm].name; 52009885543Smrg input_string = VideoInputs[input].name; 521beef1b22Smrg snprintf(channel_string, sizeof(channel_string), "%d", channel); 52209885543Smrg enc[i].id = i; 523beef1b22Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10 524beef1b22Smrg if (Xasprintf(&name_string, "%s-%s-%s", 525beef1b22Smrg norm_string, input_string, channel_string) < 0) 526beef1b22Smrg LEAVE(-1); 527beef1b22Smrg#else 528beef1b22Smrg name_string = Xprintf("%s-%s-%s", 529beef1b22Smrg norm_string, input_string, channel_string); 530beef1b22Smrg if (NULL == name_string) 5317104f784Smrg LEAVE(-1); 532beef1b22Smrg#endif 533beef1b22Smrg enc[i].name = name_string; 5347104f784Smrg 53509885543Smrg enc[i].width = VideoNorms[norm].Wa; 53609885543Smrg enc[i].height = VideoNorms[norm].Ha; 53709885543Smrg enc[i].rate = VideoNorms[norm].rate; 53809885543Smrg 5397104f784Smrg LEAVE(0); 54009885543Smrg} 54109885543Smrg 54209885543Smrg 54309885543Smrg/** 54409885543Smrg * builds XF86VideoEncodings with all legal combinations of video norm, 54509885543Smrg * video input format and video input channel 54609885543Smrg */ 54709885543Smrgstatic void 54809885543SmrgSMI_BuildEncodings(SMI_PortPtr p) 54909885543Smrg{ 55009885543Smrg int ch, n; 55109885543Smrg 5527104f784Smrg ENTER(); 55309885543Smrg 55409885543Smrg /* allocate memory for encoding array */ 555beef1b22Smrg p->enc = calloc(N_ENCODINGS, sizeof(XF86VideoEncodingRec)); 55609885543Smrg if (NULL == p->enc) 55709885543Smrg goto fail; 558beef1b22Smrg 55909885543Smrg /* allocate memory for video norm array */ 560beef1b22Smrg p->norm = calloc(N_ENCODINGS, sizeof(int)); 56109885543Smrg if (NULL == p->norm) 56209885543Smrg goto fail; 563beef1b22Smrg 56409885543Smrg /* allocate memory for video input format array */ 565beef1b22Smrg p->input = calloc(N_ENCODINGS, sizeof(int)); 56609885543Smrg if (NULL == p->input) 56709885543Smrg goto fail; 568beef1b22Smrg 56909885543Smrg /* allocate memory for video channel number array */ 570beef1b22Smrg p->channel = calloc(N_ENCODINGS, sizeof(int)); 57109885543Smrg if (NULL == p->channel) 57209885543Smrg goto fail; 57309885543Smrg 57409885543Smrg /* fill arrays */ 57509885543Smrg p->nenc = 0; 57609885543Smrg for (ch = 0; ch < N_COMPOSITE_CHANNELS; ch++) { 57709885543Smrg for (n = 0; n < N_VIDEO_NORMS; n++) { 57809885543Smrg SMI_AddEncoding(p->enc, p->nenc, n, VID_COMPOSITE, ch); 57909885543Smrg p->norm[p->nenc] = n; 58009885543Smrg p->input[p->nenc] = VID_COMPOSITE; 58109885543Smrg p->channel[p->nenc] = ch; 58209885543Smrg p->nenc++; 58309885543Smrg } 58409885543Smrg } 58509885543Smrg for (ch = 0; ch < N_SVIDEO_CHANNELS; ch++) { 58609885543Smrg for (n = 0; n < N_VIDEO_NORMS; n++) { 58709885543Smrg SMI_AddEncoding(p->enc, p->nenc, n, VID_SVIDEO, ch); 58809885543Smrg p->norm[p->nenc] = n; 58909885543Smrg p->input[p->nenc] = VID_SVIDEO; 59009885543Smrg p->channel[p->nenc] = ch; 59109885543Smrg p->nenc++; 59209885543Smrg } 59309885543Smrg } 5947104f784Smrg LEAVE(); 59509885543Smrg 59609885543Smrg fail: 5977b58d2e0Smrg free(p->input); 59809885543Smrg p->input = NULL; 5997b58d2e0Smrg free(p->norm); 60009885543Smrg p->norm = NULL; 6017b58d2e0Smrg free(p->channel); 60209885543Smrg p->channel = NULL; 6037b58d2e0Smrg free(p->enc); 60409885543Smrg p->enc = NULL; 60509885543Smrg p->nenc = 0; 6067104f784Smrg LEAVE(); 60709885543Smrg} 60809885543Smrg 60909885543Smrg 61009885543Smrg/******************************************************************************\ 61109885543Smrg** ** 61209885543Smrg** X V E X T E N S I O N I N T E R F A C E ** 61309885543Smrg** ** 61409885543Smrg\******************************************************************************/ 61509885543Smrg 61609885543Smrgvoid 61709885543SmrgSMI_InitVideo(ScreenPtr pScreen) 61809885543Smrg{ 619b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 62009885543Smrg XF86VideoAdaptorPtr *ptrAdaptors, *newAdaptors = NULL; 62109885543Smrg XF86VideoAdaptorPtr newAdaptor = NULL; 62209885543Smrg int numAdaptors; 62309885543Smrg 6247104f784Smrg ENTER(); 62509885543Smrg 62609885543Smrg numAdaptors = xf86XVListGenericAdaptors(pScrn, &ptrAdaptors); 62709885543Smrg 6287104f784Smrg DEBUG("numAdaptors=%d\n", numAdaptors); 62909885543Smrg 6307104f784Smrg newAdaptor = SMI_SetupVideo(pScreen); 6317104f784Smrg DEBUG("newAdaptor=%p\n", newAdaptor); 6327104f784Smrg SMI_InitOffscreenImages(pScreen); 63309885543Smrg 63409885543Smrg if (newAdaptor != NULL) { 63509885543Smrg if (numAdaptors == 0) { 63609885543Smrg numAdaptors = 1; 63709885543Smrg ptrAdaptors = &newAdaptor; 63809885543Smrg } else { 6397b58d2e0Smrg newAdaptors = malloc((numAdaptors + 1) * 64009885543Smrg sizeof(XF86VideoAdaptorPtr*)); 64109885543Smrg if (newAdaptors != NULL) { 64209885543Smrg memcpy(newAdaptors, ptrAdaptors, 64309885543Smrg numAdaptors * sizeof(XF86VideoAdaptorPtr)); 64409885543Smrg newAdaptors[numAdaptors++] = newAdaptor; 64509885543Smrg ptrAdaptors = newAdaptors; 64609885543Smrg } 64709885543Smrg } 64809885543Smrg } 64909885543Smrg 65009885543Smrg if (numAdaptors != 0) { 6517104f784Smrg DEBUG("ScreenInit %i\n",numAdaptors); 65209885543Smrg xf86XVScreenInit(pScreen, ptrAdaptors, numAdaptors); 65309885543Smrg } 65409885543Smrg 6557b58d2e0Smrg free(newAdaptors); 65609885543Smrg 6577104f784Smrg LEAVE(); 65809885543Smrg} 65909885543Smrg 66009885543Smrg 66109885543Smrg/*************************************************************************/ 66209885543Smrg 66309885543Smrg/* 66409885543Smrg * Video codec controls 66509885543Smrg */ 66609885543Smrg 66709885543Smrg#if 0 66809885543Smrg/** 66909885543Smrg * scales value value of attribute i to range min, max 67009885543Smrg */ 67109885543Smrgstatic int 67209885543SmrgScale(int i, int value, int min, int max) 67309885543Smrg{ 67409885543Smrg return min + (value - SMI_VideoAttributes[i].min_value) * (max - min) / 67509885543Smrg (SMI_VideoAttributes[i].max_value - SMI_VideoAttributes[i].min_value); 67609885543Smrg} 67709885543Smrg#endif 67809885543Smrg/** 67909885543Smrg * sets video decoder attributes channel, encoding, brightness, contrast, saturation, hue 68009885543Smrg */ 68109885543Smrgstatic int 68209885543SmrgSetAttr(ScrnInfoPtr pScrn, int i, int value) 68309885543Smrg{ 68409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 68509885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 68609885543Smrg 68709885543Smrg if (i < XV_ENCODING || i > XV_HUE) 68809885543Smrg return BadMatch; 68909885543Smrg 69009885543Smrg /* clamps value to attribute range */ 69109885543Smrg value = CLAMP(value, SMI_VideoAttributes[i].min_value, 69209885543Smrg SMI_VideoAttributes[i].max_value); 69309885543Smrg 69409885543Smrg if (i == XV_BRIGHTNESS) { 69509885543Smrg int my_value = (value <= 128? value + 128 : value - 128); 69609885543Smrg SetKeyReg(pSmi, 0x5C, 0xEDEDED | (my_value << 24)); 69709885543Smrg } else if (pPort->I2CDev.SlaveAddr == SAA7110) { 69809885543Smrg return SetAttrSAA7110(pScrn, i, value); 69909885543Smrg } else if (pPort->I2CDev.SlaveAddr == SAA7111) { 70009885543Smrg return SetAttrSAA7111(pScrn, i, value); 70109885543Smrg } 70209885543Smrg#if 0 70309885543Smrg else { 70409885543Smrg return XvBadAlloc; 70509885543Smrg } 70609885543Smrg#endif 70709885543Smrg 70809885543Smrg return Success; 70909885543Smrg} 71009885543Smrg 71109885543Smrg 71209885543Smrg/** 71309885543Smrg * sets SAA7110 video decoder attributes channel, encoding, brightness, contrast, saturation, hue 71409885543Smrg */ 71509885543Smrgstatic int 71609885543SmrgSetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value) 71709885543Smrg{ 71809885543Smrg /* not supported */ 71909885543Smrg return XvBadAlloc; 72009885543Smrg} 72109885543Smrg 72209885543Smrg 72309885543Smrg/** 72409885543Smrg * sets SAA7111 video decoder attributes channel, encoding, 72509885543Smrg * brightness, contrast, saturation, hue 72609885543Smrg */ 72709885543Smrgstatic int 72809885543SmrgSetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value) 72909885543Smrg{ 73009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 73109885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 73209885543Smrg 73309885543Smrg if (i == XV_ENCODING) { 73409885543Smrg int norm; 73509885543Smrg int input; 73609885543Smrg int channel; 73709885543Smrg norm = pPort->norm[value]; 73809885543Smrg input = pPort->input[value]; 73909885543Smrg channel = pPort->channel[value]; 74009885543Smrg 7417104f784Smrg DEBUG("SetAttribute XV_ENCODING: %d. norm=%d input=%d channel=%d\n", 7427104f784Smrg value, norm, input, channel); 74309885543Smrg 74409885543Smrg /* set video norm */ 74509885543Smrg if (!xf86I2CWriteVec(&(pPort->I2CDev), SAA7111VideoStd[norm], 74609885543Smrg ENTRIES(SAA7111VideoStd[norm]) / 2)) { 74709885543Smrg return XvBadAlloc; 74809885543Smrg } 74909885543Smrg /* set video input format and channel */ 75009885543Smrg if (input == VID_COMPOSITE) { 75109885543Smrg if (!xf86I2CWriteVec(&(pPort->I2CDev), 75209885543Smrg SAA7111CompositeChannelSelect[channel], 75309885543Smrg ENTRIES(SAA7111CompositeChannelSelect[channel]) / 2)) { 75409885543Smrg return XvBadAlloc; 75509885543Smrg } 75609885543Smrg } else { 75709885543Smrg if (!xf86I2CWriteVec(&(pPort->I2CDev), 75809885543Smrg SAA7111SVideoChannelSelect[channel], 75909885543Smrg ENTRIES(SAA7111SVideoChannelSelect[channel]) / 2)) { 76009885543Smrg return XvBadAlloc; 76109885543Smrg } 76209885543Smrg } 76309885543Smrg } else if (i >= XV_CAPTURE_BRIGHTNESS && i <= XV_HUE) { 76409885543Smrg int slave_adr = 0; 76509885543Smrg 76609885543Smrg switch (i) { 76709885543Smrg 76809885543Smrg case XV_CAPTURE_BRIGHTNESS: 7697104f784Smrg DEBUG("SetAttribute XV_BRIGHTNESS: %d\n", value); 77009885543Smrg slave_adr = 0x0a; 77109885543Smrg break; 77209885543Smrg 77309885543Smrg case XV_CONTRAST: 7747104f784Smrg DEBUG("SetAttribute XV_CONTRAST: %d\n", value); 77509885543Smrg slave_adr = 0x0b; 77609885543Smrg break; 77709885543Smrg 77809885543Smrg case XV_SATURATION: 7797104f784Smrg DEBUG("SetAttribute XV_SATURATION: %d\n", value); 78009885543Smrg slave_adr = 0x0c; 78109885543Smrg break; 78209885543Smrg 78309885543Smrg case XV_HUE: 7847104f784Smrg DEBUG("SetAttribute XV_HUE: %d\n", value); 78509885543Smrg slave_adr = 0x0d; 78609885543Smrg break; 78709885543Smrg 78809885543Smrg default: 78909885543Smrg return XvBadAlloc; 79009885543Smrg } 79109885543Smrg if (!xf86I2CWriteByte(&(pPort->I2CDev), slave_adr, (value & 0xff))) 79209885543Smrg return XvBadAlloc; 79309885543Smrg } else { 79409885543Smrg return BadMatch; 79509885543Smrg } 79609885543Smrg 79709885543Smrg /* debug: show registers */ 79809885543Smrg { 79909885543Smrg I2CByte i2c_bytes[32]; 800df9ffc95Smrg int j; 80109885543Smrg xf86I2CReadBytes(&(pPort->I2CDev), 0, i2c_bytes, 32); 8027104f784Smrg DEBUG("SAA7111 Registers\n"); 803df9ffc95Smrg for (j=0; j<32; j++) { 804df9ffc95Smrg DEBUG("%02X=%02X ", j, i2c_bytes[j]); 805beef1b22Smrg if ((j&7) == 7) { 806beef1b22Smrg DEBUG("\n"); 807beef1b22Smrg } 80809885543Smrg } 80909885543Smrg } 81009885543Smrg 81109885543Smrg return Success; 81209885543Smrg} 81309885543Smrg 81409885543Smrg 81509885543Smrg/******************************************************************************\ 81609885543Smrg** ** 81709885543Smrg** V I D E O M A N A G E M E N T ** 81809885543Smrg** ** 81909885543Smrg\******************************************************************************/ 82009885543Smrg 82109885543Smrgstatic XF86VideoAdaptorPtr 82209885543SmrgSMI_SetupVideo(ScreenPtr pScreen) 82309885543Smrg{ 824b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 82509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 82609885543Smrg SMI_PortPtr smiPortPtr; 82709885543Smrg XF86VideoAdaptorPtr ptrAdaptor; 82809885543Smrg 8297104f784Smrg ENTER(); 83009885543Smrg 8317b58d2e0Smrg ptrAdaptor = calloc(1, sizeof(XF86VideoAdaptorRec) + 83209885543Smrg sizeof(DevUnion) + sizeof(SMI_PortRec)); 8337104f784Smrg if (ptrAdaptor == NULL) 8347104f784Smrg LEAVE(NULL); 83509885543Smrg 83609885543Smrg ptrAdaptor->type = XvInputMask 83709885543Smrg#if SMI_USE_CAPTURE 83809885543Smrg | XvOutputMask 83909885543Smrg | XvVideoMask 84009885543Smrg#endif 84109885543Smrg | XvImageMask 84209885543Smrg | XvWindowMask 84309885543Smrg ; 84409885543Smrg 8457104f784Smrg ptrAdaptor->flags = VIDEO_OVERLAID_IMAGES; 8467104f784Smrg if (IS_MSOC(pSmi)) { 8477104f784Smrg ptrAdaptor->name = "Silicon Motion MSOC Series Video Engine"; 8487104f784Smrg } 8497104f784Smrg else 8507104f784Smrg ptrAdaptor->name = "Silicon Motion Lynx Series Video Engine"; 85109885543Smrg 85209885543Smrg ptrAdaptor->nPorts = 1; 85309885543Smrg ptrAdaptor->pPortPrivates = (DevUnion*) &ptrAdaptor[1]; 85409885543Smrg ptrAdaptor->pPortPrivates[0].ptr = (pointer) &ptrAdaptor->pPortPrivates[1]; 85509885543Smrg 85609885543Smrg smiPortPtr = (SMI_PortPtr) ptrAdaptor->pPortPrivates[0].ptr; 85709885543Smrg 85809885543Smrg SMI_BuildEncodings(smiPortPtr); 85909885543Smrg ptrAdaptor->nEncodings = smiPortPtr->nenc; 86009885543Smrg ptrAdaptor->pEncodings = smiPortPtr->enc; 86109885543Smrg#if 0 862beef1b22Smrg /* aaa what's this? */ 86309885543Smrg for (i = 0; i < nElems(SMI_VideoEncodings); i++) 86409885543Smrg { 86509885543Smrg SMI_VideoEncodings[i].width = pSmi->lcdWidth; 86609885543Smrg SMI_VideoEncodings[i].height = pSmi->lcdHeight; 86709885543Smrg } 86809885543Smrg#endif 86909885543Smrg 87009885543Smrg ptrAdaptor->nFormats = nElems(SMI_VideoFormats); 87109885543Smrg ptrAdaptor->pFormats = SMI_VideoFormats; 87209885543Smrg 87309885543Smrg ptrAdaptor->nAttributes = nElems(SMI_VideoAttributes); 87409885543Smrg ptrAdaptor->pAttributes = SMI_VideoAttributes; 87509885543Smrg 8767104f784Smrg if (IS_MSOC(pSmi)) { 8777104f784Smrg ptrAdaptor->nImages = nElems(SMI501_VideoImages); 8787104f784Smrg ptrAdaptor->pImages = SMI501_VideoImages; 8797104f784Smrg } 8807104f784Smrg else { 8817104f784Smrg ptrAdaptor->nImages = nElems(SMI_VideoImages); 8827104f784Smrg ptrAdaptor->pImages = SMI_VideoImages; 8837104f784Smrg } 88409885543Smrg 88509885543Smrg#if SMI_USE_CAPTURE 8867104f784Smrg if (pSmi->Chipset == SMI_COUGAR3DR || IS_MSOC(pSmi)) 88709885543Smrg ptrAdaptor->PutVideo = NULL; 88809885543Smrg else 88909885543Smrg ptrAdaptor->PutVideo = SMI_PutVideo; 89009885543Smrg ptrAdaptor->PutStill = NULL; 89109885543Smrg ptrAdaptor->GetVideo = NULL; 89209885543Smrg ptrAdaptor->GetStill = NULL; 89309885543Smrg#else 89409885543Smrg ptrAdaptor->PutVideo = NULL; 89509885543Smrg ptrAdaptor->PutStill = NULL; 89609885543Smrg ptrAdaptor->GetVideo = NULL; 89709885543Smrg ptrAdaptor->GetStill = NULL; 89809885543Smrg#endif 89909885543Smrg ptrAdaptor->StopVideo = SMI_StopVideo; 90009885543Smrg ptrAdaptor->SetPortAttribute = SMI_SetPortAttribute; 90109885543Smrg ptrAdaptor->GetPortAttribute = SMI_GetPortAttribute; 90209885543Smrg ptrAdaptor->QueryBestSize = SMI_QueryBestSize; 90309885543Smrg ptrAdaptor->PutImage = SMI_PutImage; 90409885543Smrg ptrAdaptor->QueryImageAttributes = SMI_QueryImageAttributes; 90509885543Smrg 90609885543Smrg smiPortPtr->Attribute[XV_COLORKEY] = pSmi->videoKey; 90709885543Smrg smiPortPtr->Attribute[XV_INTERLACED] = pSmi->interlaced; 90809885543Smrg smiPortPtr->videoStatus = 0; 90909885543Smrg 91009885543Smrg#if 0 91109885543Smrg /* aaa does not work ? */ 91209885543Smrg if (xf86I2CProbeAddress(pSmi->I2C, SAA7111)) 9137104f784Smrg LEAVE(NULL); 9147104f784Smrg DEBUG("SAA7111 detected\n"); 91509885543Smrg#endif 91609885543Smrg 91709885543Smrg smiPortPtr->I2CDev.DevName = "SAA 7111A"; 91809885543Smrg smiPortPtr->I2CDev.SlaveAddr = SAA7111; 91909885543Smrg smiPortPtr->I2CDev.pI2CBus = pSmi->I2C; 92009885543Smrg 9217104f784Smrg 9227104f784Smrg if (!IS_MSOC(pSmi) && xf86I2CDevInit(&(smiPortPtr->I2CDev))) { 92309885543Smrg 92409885543Smrg if (xf86I2CWriteVec(&(smiPortPtr->I2CDev), SAA7111InitData, ENTRIES(SAA7111InitData) / 2)) { 92509885543Smrg xvEncoding = MAKE_ATOM(XV_ENCODING_NAME); 92609885543Smrg xvHue = MAKE_ATOM(XV_HUE_NAME); 92709885543Smrg xvSaturation = MAKE_ATOM(XV_SATURATION_NAME); 92809885543Smrg xvContrast = MAKE_ATOM(XV_CONTRAST_NAME); 92909885543Smrg 93009885543Smrg xvInterlaced = MAKE_ATOM(XV_INTERLACED_NAME); 931beef1b22Smrg DEBUG("SAA7111 initialized\n"); 93209885543Smrg 93309885543Smrg } else { 93409885543Smrg xf86DestroyI2CDevRec(&(smiPortPtr->I2CDev),FALSE); 93509885543Smrg smiPortPtr->I2CDev.SlaveAddr = 0; 93609885543Smrg } 93709885543Smrg } else 93809885543Smrg smiPortPtr->I2CDev.SlaveAddr = 0; 93909885543Smrg 94009885543Smrg#if defined(REGION_NULL) 94109885543Smrg REGION_NULL(pScreen, &smiPortPtr->clip); 94209885543Smrg#else 94309885543Smrg REGION_INIT(pScreen, &smiPortPtr->clip, NullBox, 0); 94409885543Smrg#endif 94509885543Smrg 94609885543Smrg pSmi->ptrAdaptor = ptrAdaptor; 94709885543Smrg pSmi->BlockHandler = pScreen->BlockHandler; 94809885543Smrg pScreen->BlockHandler = SMI_BlockHandler; 94909885543Smrg 95009885543Smrg xvColorKey = MAKE_ATOM(XV_COLORKEY_NAME); 95109885543Smrg xvBrightness = MAKE_ATOM(XV_BRIGHTNESS_NAME); 95209885543Smrg xvCapBrightness = MAKE_ATOM(XV_CAPTURE_BRIGHTNESS_NAME); 95309885543Smrg 95409885543Smrg SMI_ResetVideo(pScrn); 9557104f784Smrg 9567104f784Smrg LEAVE(ptrAdaptor); 95709885543Smrg} 95809885543Smrg 95909885543Smrg 96009885543Smrgstatic void 96109885543SmrgSMI_ResetVideo(ScrnInfoPtr pScrn) 96209885543Smrg{ 96309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 96409885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 96509885543Smrg int r, g, b; 96609885543Smrg 9677104f784Smrg ENTER(); 96809885543Smrg 96909885543Smrg SetAttr(pScrn, XV_ENCODING, 0); /* Encoding = pal-composite-0 */ 97009885543Smrg SetAttr(pScrn, XV_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */ 97109885543Smrg SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, 128); /* Brightness = 128 (CCIR level) */ 97209885543Smrg SetAttr(pScrn, XV_CONTRAST, 71); /* Contrast = 71 (CCIR level) */ 97309885543Smrg SetAttr(pScrn, XV_SATURATION, 64); /* Color saturation = 64 (CCIR level) */ 97409885543Smrg SetAttr(pScrn, XV_HUE, 0); /* Hue = 0 */ 97509885543Smrg 97609885543Smrg switch (pScrn->depth) { 97709885543Smrg case 8: 97809885543Smrg SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0x00FF); 97909885543Smrg SetKeyReg(pSmi, FPR08, 0); 98009885543Smrg break; 98109885543Smrg case 15: 98209885543Smrg case 16: 98309885543Smrg SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0xFFFF); 98409885543Smrg SetKeyReg(pSmi, FPR08, 0); 98509885543Smrg break; 98609885543Smrg default: 98709885543Smrg r = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.red) >> pScrn->offset.red; 98809885543Smrg g = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.green) >> pScrn->offset.green; 98909885543Smrg b = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.blue) >> pScrn->offset.blue; 99009885543Smrg SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); 99109885543Smrg SetKeyReg(pSmi, FPR08, 0); 99209885543Smrg break; 99309885543Smrg } 99409885543Smrg 99509885543Smrg SetKeyReg(pSmi, FPR5C, 0xEDEDED | (pPort->Attribute[XV_BRIGHTNESS] << 24)); 99609885543Smrg 9977104f784Smrg LEAVE(); 99809885543Smrg} 99909885543Smrg 100009885543Smrg 100109885543Smrg#if SMI_USE_CAPTURE 100209885543Smrgstatic int 100309885543SmrgSMI_PutVideo( 100409885543Smrg ScrnInfoPtr pScrn, 100509885543Smrg short vid_x, 100609885543Smrg short vid_y, 100709885543Smrg short drw_x, 100809885543Smrg short drw_y, 100909885543Smrg short vid_w, 101009885543Smrg short vid_h, 101109885543Smrg short drw_w, 101209885543Smrg short drw_h, 101309885543Smrg RegionPtr clipBoxes, 101409885543Smrg pointer data, 101509885543Smrg DrawablePtr pDraw 101609885543Smrg) 101709885543Smrg{ 101809885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 101909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 102009885543Smrg CARD32 vid_pitch, vid_address; 102109885543Smrg CARD32 vpr00, cpr00; 102209885543Smrg int xscale, yscale; 102309885543Smrg BoxRec dstBox; 102409885543Smrg INT32 x1, y1, x2, y2; 102509885543Smrg int norm; 102609885543Smrg int size, width, height, fbPitch; 102709885543Smrg int top, left; 10287104f784Smrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); 10297104f784Smrg xf86CrtcPtr crtc; 103009885543Smrg 10317104f784Smrg ENTER(); 103209885543Smrg 10337104f784Smrg DEBUG("Interlaced Video %d\n", pPort->Attribute[XV_INTERLACED]); 103409885543Smrg 103509885543Smrg if (!pPort->Attribute[XV_INTERLACED]) { 103609885543Smrg /* no interlace: lines will be doubled */ 103709885543Smrg vid_h /= 2; 103809885543Smrg } 103909885543Smrg 104009885543Smrg /* field start aaa*/ 104109885543Smrg norm = pPort->norm[pPort->Attribute[XV_ENCODING]]; 104209885543Smrg vid_x += VideoNorms[norm].HStart; 104309885543Smrg vid_y += VideoNorms[norm].VStart; 104409885543Smrg /* only even values allowed (UV-phase) */ 104509885543Smrg vid_x &= ~1; 104609885543Smrg 10477104f784Smrg DEBUG("vid_x=%d vid_y=%d drw_x=%d drw_y=%d " 10487104f784Smrg "vid_w=%d vid_h=%d drw_w=%d drw_h=%d\n", 10497104f784Smrg vid_x, vid_y, drw_x, drw_y, vid_w, vid_h, drw_w, drw_h); 105009885543Smrg 105109885543Smrg x1 = vid_x; 105209885543Smrg y1 = vid_y; 105309885543Smrg x2 = vid_x + vid_w; 105409885543Smrg y2 = vid_y + vid_h; 105509885543Smrg 105609885543Smrg width = vid_w; 105709885543Smrg height = vid_h; 105809885543Smrg 105909885543Smrg dstBox.x1 = drw_x; 106009885543Smrg dstBox.y1 = drw_y; 106109885543Smrg dstBox.x2 = drw_x + drw_w; 106209885543Smrg dstBox.y2 = drw_y + drw_h; 106309885543Smrg 10647104f784Smrg if(!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height)) 10657104f784Smrg LEAVE(Success); 10667104f784Smrg 10677b58d2e0Smrg if (crtc != crtcConf->crtc[0]) 10687104f784Smrg LEAVE(Success); 106909885543Smrg 10707104f784Smrg /* Transform dstBox to the CRTC coordinates */ 10717104f784Smrg dstBox.x1 -= crtc->x; 10727104f784Smrg dstBox.y1 -= crtc->y; 10737104f784Smrg dstBox.x2 -= crtc->x; 10747104f784Smrg dstBox.y2 -= crtc->y; 107509885543Smrg 10767104f784Smrg DEBUG("Clip: x1=%d y1=%d x2=%d y2=%d\n", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); 107709885543Smrg 107809885543Smrg vid_pitch = (vid_w * 2 + 7) & ~7; 107909885543Smrg 108009885543Smrg vpr00 = READ_VPR(pSmi, 0x00) & ~0x0FF000FF; 108109885543Smrg cpr00 = READ_CPR(pSmi, 0x00) & ~0x000FFF00; 108209885543Smrg 108309885543Smrg /* vpr00: 108409885543Smrg Bit 2..0 = 6: Video Window I Format = YUV4:2:2 108509885543Smrg Bit 3 = 1: Video Window I Enable = enabled 108609885543Smrg Bit 4 = 0: Video Window I YUV Averaging = disabled 108709885543Smrg Bit 5 = 0: Video Window I Hor. Replication = disabled 108809885543Smrg Bit 6 = 0: Video Window I data doubling = disabled 108909885543Smrg Bit 14..8 = 0: Video Window II = disabled 109009885543Smrg Bit 18..16 = 0: Graphics Data Format = 8-bit index 109109885543Smrg Bit 19 = 0: Top Video Window Select = window I 109209885543Smrg Bit 20 = 1: Color Key for Window I = enabled 109309885543Smrg Bit 21 = 0: Vertical Interpolation = s. below 109409885543Smrg Bit 22 = 0: Flicker Reduction for TV Modes = disabled 109509885543Smrg Bit 23 = 0: Fixed Vertical Interpolation = disabled 109609885543Smrg Bit 24 = 1: Select Video Window I Source Addr = 109709885543Smrg Bit 25 = 0: Enable V0FIFO to fetch 8-Bit color data = disabled 109809885543Smrg Bit 26 = 0: 109909885543Smrg Bit 27 = 1: Color Key for Window II = disabled 110009885543Smrg Bit 31..28 = reserved 110109885543Smrg */ 110209885543Smrg if (pPort->Attribute[XV_INTERLACED]) { 110309885543Smrg /* 110409885543Smrg Bit 21 = 0: Vertical Interpolation = disabled 110509885543Smrg Bit 24 = 0: Select Video Window I Source Addr = 0 110609885543Smrg */ 110709885543Smrg vpr00 |= 0x0010000E; 110809885543Smrg } else { 110909885543Smrg /* 1110e4f6584cSmrg Bit 21 = 1: Vertical Interpolation = enabled 111109885543Smrg Bit 24 = 1: Select Video Window I Source Addr = 1 111209885543Smrg 1= Video window I source addr = capture port buffer ? 111309885543Smrg */ 111409885543Smrg vpr00 |= 0x0130000E; 111509885543Smrg } 111609885543Smrg 111709885543Smrg /* cpr00: 111809885543Smrg Bit 0 = 1: Video Capture Enable = enabled 1119beef1b22Smrg Bit 8 = 0: Capture Control = continuous 112009885543Smrg Bit 9 = 0: Double Buffer Enable = s. below 112109885543Smrg Bit 10 = 0: Interlace Data Capture = s. below 112209885543Smrg Bit 13..11 = 0: Frame Skip Enable = s. below 112309885543Smrg Bit 15..14 = 0: Video Capture Input Format = YUV4:2:2 112409885543Smrg Bit 17..16 = 0: Enable Hor. Reduction = s. below 112509885543Smrg Bit 19..18 = 0: Enable Vert. Reduction = s. below 112609885543Smrg Bit 21..20 = 0: Enable Hor. Filtering = s. below 112709885543Smrg Bit 22 = 0: HREF Polarity = high active 112809885543Smrg Bit 23 = 0: VREF Polarity = high active 112909885543Smrg Bit 24 = 1: Field Detection Method VSYNC edge = rising 113009885543Smrg */ 113109885543Smrg if (pPort->Attribute[XV_INTERLACED]) { 113209885543Smrg /* 113309885543Smrg Bit 9 = 1: Double Buffer Enable = enabled 113409885543Smrg Bit 10 = 1: Interlace Data Capture = enabled 113509885543Smrg Bit 13..11 = 0: Frame Skip Enable = no skip 113609885543Smrg */ 113709885543Smrg cpr00 |= 0x01000601; 113809885543Smrg } else { 113909885543Smrg /* 114009885543Smrg Bit 9 = 0: Double Buffer Enable = disabled 114109885543Smrg Bit 10 = 0: Interlace Data Capture = disabled 114209885543Smrg Bit 13..11 = 010: Frame Skip Enable = skip every other frame 114309885543Smrg */ 11447104f784Smrg cpr00 |= 0x01001001; 114509885543Smrg } 114609885543Smrg 114709885543Smrg if (pSmi->ByteSwap) 114809885543Smrg cpr00 |= 0x00004000; 114909885543Smrg 11507104f784Smrg fbPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15; 115109885543Smrg 115209885543Smrg if (vid_w <= drw_w) { 115309885543Smrg xscale = (256 * vid_w / drw_w) & 0xFF; 115409885543Smrg } else if (vid_w / 2 <= drw_w) { 115509885543Smrg xscale = (128 * vid_w / drw_w) & 0xFF; 115609885543Smrg width /= 2; 115709885543Smrg vid_pitch /= 2; 115809885543Smrg cpr00 |= 0x00010000; 115909885543Smrg } else if (vid_w / 4 <= drw_w) { 116009885543Smrg xscale = (64 * vid_w / drw_w) & 0xFF; 116109885543Smrg width /= 4; 116209885543Smrg vid_pitch /= 4; 116309885543Smrg cpr00 |= 0x00020000; 116409885543Smrg } else { 116509885543Smrg xscale = 0; 116609885543Smrg width /= 4; 116709885543Smrg vid_pitch /= 4; 116809885543Smrg cpr00 |= 0x00020000; 116909885543Smrg } 117009885543Smrg 117109885543Smrg if (vid_h <= drw_h) { 117209885543Smrg yscale = (256 * vid_h / drw_h) & 0xFF; 117309885543Smrg } else if (vid_h / 2 <= drw_h) { 117409885543Smrg yscale = (128 * vid_h / drw_h) & 0xFF; 117509885543Smrg height /= 2; 117609885543Smrg cpr00 |= 0x00040000; 117709885543Smrg } else if (vid_h / 4 <= drw_h) { 117809885543Smrg yscale = (64 * vid_h / drw_h) & 0xFF; 117909885543Smrg height /= 4; 118009885543Smrg cpr00 |= 0x00080000; 118109885543Smrg } else { 118209885543Smrg yscale = 0; 118309885543Smrg height /= 4; 118409885543Smrg cpr00 |= 0x00080000; 118509885543Smrg } 118609885543Smrg 118709885543Smrg do { 118809885543Smrg size = vid_pitch * height; 11897104f784Smrg DEBUG("SMI_AllocateMemory: vid_pitch=%d height=%d size=%d\n", 11907104f784Smrg vid_pitch, height, size); 119109885543Smrg pPort->video_offset = SMI_AllocateMemory(pScrn, &pPort->video_memory, size); 119209885543Smrg if (pPort->video_offset == 0) { 119309885543Smrg if ((cpr00 & 0x000C0000) == 0) { 119409885543Smrg /* height -> 1/2 height */ 119509885543Smrg yscale = (128 * vid_h / drw_h) & 0xFF; 119609885543Smrg height = vid_h / 2; 119709885543Smrg cpr00 |= 0x00040000; 119809885543Smrg } else if (cpr00 & 0x00040000) { 119909885543Smrg /* 1/2 height -> 1/4 height */ 120009885543Smrg yscale = (64 * vid_h / drw_h) & 0xFF; 120109885543Smrg height = vid_h / 4; 120209885543Smrg cpr00 ^= 0x000C0000; 120309885543Smrg } else { 120409885543Smrg /* 1/4 height */ 120509885543Smrg if ((cpr00 & 0x00030000) == 0) { 120609885543Smrg /* width -> 1/2 width */ 120709885543Smrg xscale = (128 * vid_w / drw_w) & 0xFF; 120809885543Smrg width = vid_w / 2; 120909885543Smrg cpr00 |= 0x00010000; 121009885543Smrg } else if (cpr00 & 0x00010000) { 121109885543Smrg /* 1/2 width -> 1/4 width */ 121209885543Smrg xscale = (64 * vid_w / drw_w) & 0xFF; 121309885543Smrg width = vid_w / 4; 121409885543Smrg cpr00 ^= 0x00030000; 121509885543Smrg } else { 12167104f784Smrg DEBUG("allocate error\n"); 12177104f784Smrg LEAVE(BadAlloc); 121809885543Smrg } 121909885543Smrg } 122009885543Smrg } 122109885543Smrg } while (pPort->video_offset == 0); 122209885543Smrg 12237104f784Smrg DEBUG("xscale==%d yscale=%d width=%d height=%d\n", 12247104f784Smrg xscale, yscale, width, height); 122509885543Smrg 1226beef1b22Smrg /* aaa what's this ----------------------v ? 122709885543Smrg vid_address = (pPort->area->box.y1 * fbPitch) + ((y1 >> 16) * vid_pitch);*/ 122809885543Smrg vid_address = pPort->video_offset; 122909885543Smrg 12307104f784Smrg DEBUG("test RegionsEqual\n"); 123109885543Smrg if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) 123209885543Smrg { 123309885543Smrg DEBUG((VERBLEV, "RegionCopy\n")); 123409885543Smrg REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); 12357104f784Smrg DEBUG("FillKey\n"); 123609885543Smrg xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes); 123709885543Smrg 123809885543Smrg } 123909885543Smrg 124009885543Smrg left = x1 >> 16; 124109885543Smrg top = y1 >> 16; 124209885543Smrg width = (x2 - x1) >> 16; 124309885543Smrg height = (y2 - y1) >> 16; 124409885543Smrg 12457104f784Smrg if (!IS_MSOC(pSmi)) 12467104f784Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 12477104f784Smrg 0x21, 12487104f784Smrg VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 12497104f784Smrg 0x21) & ~0x04); 125009885543Smrg WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) | 0x00200000); 125109885543Smrg /* Video Window I Left and Top Boundaries */ 125209885543Smrg WRITE_VPR(pSmi, 0x14, dstBox.x1 + (dstBox.y1 << 16)); 125309885543Smrg /* Video Window I Right and Bottom Boundaries */ 125409885543Smrg WRITE_VPR(pSmi, 0x18, dstBox.x2 + (dstBox.y2 << 16)); 125509885543Smrg /* Video Window I Source Width and Offset */ 125609885543Smrg WRITE_VPR(pSmi, 0x20, (vid_pitch / 8) + ((vid_pitch / 8) << 16)); 125709885543Smrg /* Video Window I Stretch Factor */ 125809885543Smrg WRITE_VPR(pSmi, 0x24, (xscale << 8) + yscale); 125909885543Smrg 126009885543Smrg if (pPort->Attribute[XV_INTERLACED]) { 126109885543Smrg /* Video Window II Left and Top Boundaries */ 126209885543Smrg WRITE_VPR(pSmi, 0x28, dstBox.x1 + (dstBox.y1 << 16)); 126309885543Smrg /* Video Window II Right and Bottom Boundaries */ 126409885543Smrg WRITE_VPR(pSmi, 0x2C, dstBox.x2 + (dstBox.y2 << 16)); 126509885543Smrg /* Video Window II Source Width and Offset */ 126609885543Smrg WRITE_VPR(pSmi, 0x34, (vid_pitch / 8) + ((vid_pitch / 8) << 16)); 126709885543Smrg /* Video Window II Stretch Factor */ 126809885543Smrg WRITE_VPR(pSmi, 0x38, (xscale << 8) + yscale); 126909885543Smrg 127009885543Smrg /* Video Window I Source Start Address */ 127109885543Smrg WRITE_VPR(pSmi, 0x1C, vid_address / 8); 127209885543Smrg /* Video Window II Source Start Address */ 127309885543Smrg WRITE_VPR(pSmi, 0x30, vid_address / 8); 127409885543Smrg 127509885543Smrg /* Video Window I Source Start Address */ 127609885543Smrg WRITE_VPR(pSmi, 0x48, vid_address / 8); 127709885543Smrg /* Video Window II Source Start Address */ 127809885543Smrg WRITE_VPR(pSmi, 0x4C, vid_address / 8 + vid_pitch / 8); 127909885543Smrg 128009885543Smrg /* Video Source Clipping Control */ 128109885543Smrg WRITE_CPR(pSmi, 0x04, left + ((top/2) << 16)); 128209885543Smrg /* Video Source Capture Size Control */ 128309885543Smrg WRITE_CPR(pSmi, 0x08, width + ((height/2) << 16)); 128409885543Smrg /* Capture Port Buffer I Source Start Address */ 128509885543Smrg WRITE_CPR(pSmi, 0x0C, vid_address / 8); 128609885543Smrg /* Capture Port Buffer II Source Start Address */ 128709885543Smrg WRITE_CPR(pSmi, 0x10, vid_address / 8 + vid_pitch / 8); 128809885543Smrg /* Capture Port Source Offset Address */ 128909885543Smrg WRITE_CPR(pSmi, 0x14, 2*(vid_pitch / 8) + ((2*(vid_pitch / 8)) << 16)); 129009885543Smrg } else { 129109885543Smrg /* Video Source Clipping Control */ 129209885543Smrg WRITE_CPR(pSmi, 0x04, left + (top << 16)); 129309885543Smrg /* Video Source Capture Size Control */ 129409885543Smrg WRITE_CPR(pSmi, 0x08, width + (height << 16)); 129509885543Smrg /* Capture Port Buffer I Source Start Address */ 129609885543Smrg WRITE_CPR(pSmi, 0x0C, vid_address / 8); 129709885543Smrg /* Capture Port Buffer II Source Start Address */ 129809885543Smrg WRITE_CPR(pSmi, 0x10, vid_address / 8); 129909885543Smrg /* Capture Port Source Offset Address */ 130009885543Smrg WRITE_CPR(pSmi, 0x14, (vid_pitch / 8) + ((vid_pitch / 8) << 16)); 130109885543Smrg } 130209885543Smrg 130309885543Smrg WRITE_CPR(pSmi, 0x00, cpr00); 130409885543Smrg WRITE_VPR(pSmi, 0x00, vpr00); 130509885543Smrg 130609885543Smrg pPort->videoStatus = CLIENT_VIDEO_ON; 13077104f784Smrg DEBUG("SMI_PutVideo success\n"); 13087104f784Smrg 13097104f784Smrg LEAVE(Success); 131009885543Smrg} 131109885543Smrg#endif 131209885543Smrg 131309885543Smrg 131409885543Smrgstatic void 131509885543SmrgSMI_StopVideo( 131609885543Smrg ScrnInfoPtr pScrn, 131709885543Smrg pointer data, 131809885543Smrg Bool shutdown 131909885543Smrg) 132009885543Smrg{ 132109885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 132209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 132309885543Smrg 13247104f784Smrg ENTER(); 132509885543Smrg 132609885543Smrg REGION_EMPTY(pScrn->pScreen, &pPort->clip); 132709885543Smrg 132809885543Smrg if (shutdown) { 132909885543Smrg if (pPort->videoStatus & CLIENT_VIDEO_ON) { 13307104f784Smrg if (pSmi->Chipset == SMI_COUGAR3DR) 133109885543Smrg WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); 13327104f784Smrg else if (IS_MSOC(pSmi)) 13337104f784Smrg WRITE_DCR(pSmi, 0x0040, READ_DCR(pSmi, 0x0040) & ~0x00000004); 13347104f784Smrg else 133509885543Smrg WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x01000008); 133609885543Smrg#if SMI_USE_CAPTURE 13377104f784Smrg if (!IS_MSOC(pSmi) && pSmi->Chipset != SMI_COUGAR3DR) { 133809885543Smrg WRITE_CPR(pSmi, 0x00, READ_CPR(pSmi, 0x00) & ~0x00000001); 133909885543Smrg WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) & ~0x00F00000); 134009885543Smrg } 134109885543Smrg#endif 134209885543Smrg } 134309885543Smrg if (pPort->video_memory != NULL) { 134409885543Smrg SMI_FreeMemory(pScrn, pPort->video_memory); 134509885543Smrg pPort->video_memory = NULL; 134609885543Smrg } 134709885543Smrg pPort->videoStatus = 0; 134809885543Smrg /* pPort->i2cDevice = 0;aaa*/ 134909885543Smrg } else { 135009885543Smrg if (pPort->videoStatus & CLIENT_VIDEO_ON) { 135109885543Smrg pPort->videoStatus |= OFF_TIMER; 135209885543Smrg pPort->offTime = currentTime.milliseconds + OFF_DELAY; 135309885543Smrg } 135409885543Smrg } 135509885543Smrg 13567104f784Smrg LEAVE(); 135709885543Smrg} 135809885543Smrg 135909885543Smrgstatic int 136009885543SmrgSMI_SetPortAttribute( 136109885543Smrg ScrnInfoPtr pScrn, 136209885543Smrg Atom attribute, 136309885543Smrg INT32 value, 136409885543Smrg pointer data 136509885543Smrg) 136609885543Smrg{ 136709885543Smrg int res; 136809885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 136909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 137009885543Smrg 13717104f784Smrg ENTER(); 137209885543Smrg 137309885543Smrg if (attribute == xvColorKey) { 137409885543Smrg int r, g, b; 137509885543Smrg 137609885543Smrg pPort->Attribute[XV_COLORKEY] = value; 137709885543Smrg switch (pScrn->depth) { 137809885543Smrg case 8: 137909885543Smrg SetKeyReg(pSmi, FPR04, value & 0x00FF); 138009885543Smrg break; 138109885543Smrg case 15: 138209885543Smrg case 16: 138309885543Smrg SetKeyReg(pSmi, FPR04, value & 0xFFFF); 138409885543Smrg break; 138509885543Smrg default: 138609885543Smrg r = (value & pScrn->mask.red) >> pScrn->offset.red; 138709885543Smrg g = (value & pScrn->mask.green) >> pScrn->offset.green; 138809885543Smrg b = (value & pScrn->mask.blue) >> pScrn->offset.blue; 138909885543Smrg SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); 139009885543Smrg break; 139109885543Smrg } 139209885543Smrg res = Success; 139309885543Smrg } else if (attribute == xvInterlaced) { 139409885543Smrg pPort->Attribute[XV_INTERLACED] = (value != 0); 139509885543Smrg res = Success; 139609885543Smrg } else if (attribute == xvEncoding) { 139709885543Smrg res = SetAttr(pScrn, XV_ENCODING, value); 139809885543Smrg } else if (attribute == xvBrightness) { 139909885543Smrg res = SetAttr(pScrn, XV_BRIGHTNESS, value); 140009885543Smrg } else if (attribute == xvCapBrightness) { 140109885543Smrg res = SetAttr(pScrn, XV_CAPTURE_BRIGHTNESS, value); 140209885543Smrg } else if (attribute == xvContrast) { 140309885543Smrg res = SetAttr(pScrn, XV_CONTRAST, value); 140409885543Smrg } else if (attribute == xvSaturation) { 140509885543Smrg res = SetAttr(pScrn, XV_SATURATION, value); 140609885543Smrg } else if (attribute == xvHue) { 140709885543Smrg res = SetAttr(pScrn, XV_HUE, value); 140809885543Smrg } else { 140909885543Smrg res = BadMatch; 141009885543Smrg } 141109885543Smrg 14127104f784Smrg LEAVE(res); 141309885543Smrg} 141409885543Smrg 141509885543Smrg 141609885543Smrgstatic int 141709885543SmrgSMI_GetPortAttribute( 141809885543Smrg ScrnInfoPtr pScrn, 141909885543Smrg Atom attribute, 142009885543Smrg INT32 *value, 142109885543Smrg pointer data 142209885543Smrg) 142309885543Smrg{ 142409885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) data; 142509885543Smrg 14267104f784Smrg ENTER(); 142709885543Smrg if (attribute == xvEncoding) 142809885543Smrg *value = pPort->Attribute[XV_ENCODING]; 142909885543Smrg else if (attribute == xvBrightness) 143009885543Smrg *value = pPort->Attribute[XV_BRIGHTNESS]; 143109885543Smrg else if (attribute == xvCapBrightness) 143209885543Smrg *value = pPort->Attribute[XV_CAPTURE_BRIGHTNESS]; 143309885543Smrg else if (attribute == xvContrast) 143409885543Smrg *value = pPort->Attribute[XV_CONTRAST]; 143509885543Smrg else if (attribute == xvSaturation) 143609885543Smrg *value = pPort->Attribute[XV_SATURATION]; 143709885543Smrg else if (attribute == xvHue) 143809885543Smrg *value = pPort->Attribute[XV_HUE]; 143909885543Smrg else if (attribute == xvColorKey) 144009885543Smrg *value = pPort->Attribute[XV_COLORKEY]; 14417104f784Smrg else 14427104f784Smrg LEAVE(BadMatch); 144309885543Smrg 14447104f784Smrg LEAVE(Success); 144509885543Smrg} 144609885543Smrg 144709885543Smrg 144809885543Smrgstatic void 144909885543SmrgSMI_QueryBestSize( 145009885543Smrg ScrnInfoPtr pScrn, 145109885543Smrg Bool motion, 145209885543Smrg short vid_w, 145309885543Smrg short vid_h, 145409885543Smrg short drw_w, 145509885543Smrg short drw_h, 145609885543Smrg unsigned int *p_w, 145709885543Smrg unsigned int *p_h, 145809885543Smrg pointer data 145909885543Smrg) 146009885543Smrg{ 146109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 146209885543Smrg 14637104f784Smrg ENTER(); 146409885543Smrg 146509885543Smrg *p_w = min(drw_w, pSmi->lcdWidth); 146609885543Smrg *p_h = min(drw_h, pSmi->lcdHeight); 146709885543Smrg 14687104f784Smrg LEAVE(); 146909885543Smrg} 147009885543Smrg 147109885543Smrg 147209885543Smrgstatic int 147309885543SmrgSMI_PutImage( 147409885543Smrg ScrnInfoPtr pScrn, 147509885543Smrg short src_x, 147609885543Smrg short src_y, 147709885543Smrg short drw_x, 147809885543Smrg short drw_y, 147909885543Smrg short src_w, 148009885543Smrg short src_h, 148109885543Smrg short drw_w, 148209885543Smrg short drw_h, 14837104f784Smrg int id, 14847104f784Smrg unsigned char *buf, 148509885543Smrg short width, 148609885543Smrg short height, 148709885543Smrg Bool sync, 148809885543Smrg RegionPtr clipBoxes, 148909885543Smrg pointer data, 149009885543Smrg DrawablePtr pDraw 149109885543Smrg) 149209885543Smrg{ 149309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 149409885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 149509885543Smrg INT32 x1, y1, x2, y2; 149609885543Smrg int bpp = 0; 149709885543Smrg int srcPitch, srcPitch2 = 0, dstPitch, size; 149809885543Smrg BoxRec dstBox; 149909885543Smrg CARD32 offset, offset2 = 0, offset3 = 0, tmp; 150009885543Smrg int left, top, nPixels, nLines; 150109885543Smrg unsigned char *dstStart; 15027104f784Smrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); 15037104f784Smrg xf86CrtcPtr crtc; 150409885543Smrg 15057104f784Smrg ENTER(); 150609885543Smrg 150709885543Smrg x1 = src_x; 150809885543Smrg y1 = src_y; 150909885543Smrg x2 = src_x + src_w; 151009885543Smrg y2 = src_y + src_h; 151109885543Smrg 151209885543Smrg dstBox.x1 = drw_x; 151309885543Smrg dstBox.y1 = drw_y; 151409885543Smrg dstBox.x2 = drw_x + drw_w; 151509885543Smrg dstBox.y2 = drw_y + drw_h; 151609885543Smrg 15177104f784Smrg if (pSmi->CSCVideo) { 15187104f784Smrg if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, 15197104f784Smrg width, height)) 15207104f784Smrg LEAVE(Success); 152109885543Smrg } 15227104f784Smrg else { 15237104f784Smrg if (!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox, 15247104f784Smrg &x1, &x2, &y1, &y2, clipBoxes, 15257104f784Smrg width, height)) 15267104f784Smrg LEAVE(Success); 152709885543Smrg 15287b58d2e0Smrg if (!crtc) 15297b58d2e0Smrg LEAVE(Success); 15307b58d2e0Smrg 15317104f784Smrg /* Transform dstBox to the CRTC coordinates */ 15327104f784Smrg dstBox.x1 -= crtc->x; 15337104f784Smrg dstBox.y1 -= crtc->y; 15347104f784Smrg dstBox.x2 -= crtc->x; 15357104f784Smrg dstBox.y2 -= crtc->y; 15367104f784Smrg } 153709885543Smrg 153809885543Smrg switch (id) { 153909885543Smrg case FOURCC_YV12: 15407104f784Smrg case FOURCC_I420: 154109885543Smrg srcPitch = (width + 3) & ~3; 154209885543Smrg offset2 = srcPitch * height; 154309885543Smrg srcPitch2 = ((width >> 1) + 3) & ~3; 154409885543Smrg offset3 = offset2 + (srcPitch2 * (height >> 1)); 15457104f784Smrg if (pSmi->CSCVideo) 15467104f784Smrg dstPitch = (((width >> 1) + 15) & ~15) << 1; 15477104f784Smrg else 15487104f784Smrg dstPitch = ((width << 1) + 15) & ~15; 154909885543Smrg break; 155009885543Smrg case FOURCC_RV24: 155109885543Smrg bpp = 3; 155209885543Smrg srcPitch = width * bpp; 155309885543Smrg dstPitch = (srcPitch + 15) & ~15; 155409885543Smrg break; 155509885543Smrg case FOURCC_RV32: 155609885543Smrg bpp = 4; 155709885543Smrg srcPitch = width * bpp; 155809885543Smrg dstPitch = (srcPitch + 15) & ~15; 155909885543Smrg break; 156009885543Smrg case FOURCC_YUY2: 156109885543Smrg case FOURCC_RV15: 156209885543Smrg case FOURCC_RV16: 156309885543Smrg default: 156409885543Smrg bpp = 2; 156509885543Smrg srcPitch = width * bpp; 156609885543Smrg dstPitch = (srcPitch + 15) & ~15; 156709885543Smrg break; 156809885543Smrg } 156909885543Smrg 157009885543Smrg size = dstPitch * height; 157109885543Smrg pPort->video_offset = SMI_AllocateMemory(pScrn, &pPort->video_memory, size); 15727104f784Smrg if (pPort->video_memory == NULL) 15737104f784Smrg LEAVE(BadAlloc); 157409885543Smrg 157509885543Smrg top = y1 >> 16; 157609885543Smrg left = (x1 >> 16) & ~1; 157709885543Smrg nPixels = ((((x2 + 0xFFFF) >> 16) + 1) & ~1) - left; 157809885543Smrg left *= bpp; 157909885543Smrg 158009885543Smrg offset = pPort->video_offset + (top * dstPitch); 158109885543Smrg dstStart = pSmi->FBBase + offset + left; 158209885543Smrg 158309885543Smrg switch(id) { 158409885543Smrg case FOURCC_YV12: 158509885543Smrg case FOURCC_I420: 158609885543Smrg top &= ~1; 158709885543Smrg tmp = ((top >> 1) * srcPitch2) + (left >> 2); 158809885543Smrg offset2 += tmp; 158909885543Smrg offset3 += tmp; 15907104f784Smrg if (pSmi->CSCVideo) 15917104f784Smrg CopyYV12ToVideoMem(buf, 15927104f784Smrg buf + offset2, buf + offset3, 15937104f784Smrg dstStart, srcPitch, srcPitch2, dstPitch, 15947104f784Smrg height, width); 15957104f784Smrg else { 15967104f784Smrg if (id == FOURCC_I420) { 15977104f784Smrg tmp = offset2; 15987104f784Smrg offset2 = offset3; 15997104f784Smrg offset3 = tmp; 16007104f784Smrg } 16017104f784Smrg nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 16027104f784Smrg xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), 16037104f784Smrg buf + offset2, buf + offset3, dstStart, 16047104f784Smrg srcPitch, srcPitch2, dstPitch, nLines, 16057104f784Smrg nPixels); 160609885543Smrg } 160709885543Smrg break; 160809885543Smrg case FOURCC_UYVY: 160909885543Smrg case FOURCC_YUY2: 161009885543Smrg default: 161109885543Smrg buf += (top * srcPitch) + left; 161209885543Smrg nLines = ((y2 + 0xffff) >> 16) - top; 161309885543Smrg xf86XVCopyPacked(buf, dstStart, srcPitch, dstPitch, nLines, nPixels); 161409885543Smrg break; 161509885543Smrg } 161609885543Smrg 16177104f784Smrg if (IS_MSOC(pSmi) || 16187104f784Smrg !REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) { 16197104f784Smrg REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); 16207104f784Smrg if (!pSmi->CSCVideo) 16217104f784Smrg xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], 16227104f784Smrg clipBoxes); 162309885543Smrg } 162409885543Smrg 16257104f784Smrg if (pSmi->Chipset == SMI_COUGAR3DR) 162609885543Smrg SMI_DisplayVideo0730(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, 162709885543Smrg &dstBox, src_w, src_h, drw_w, drw_h); 16287104f784Smrg else if (IS_MSOC(pSmi)) { 16297104f784Smrg if (pSmi->CSCVideo) 16307104f784Smrg SMI_DisplayVideo0501_CSC(pScrn, id, offset, width, height, dstPitch, 16317104f784Smrg x1, y1, x2, y2, &dstBox, 16327104f784Smrg src_w, src_h, drw_w, drw_h, clipBoxes); 16337104f784Smrg else 16347104f784Smrg SMI_DisplayVideo0501(pScrn, id, offset, width, height, dstPitch, 16357104f784Smrg x1, y1, x2, y2, &dstBox, src_w, src_h, 16367104f784Smrg drw_w, drw_h); 16377104f784Smrg } 16387104f784Smrg else{ 16397104f784Smrg if(crtc == crtcConf->crtc[0]) 16407104f784Smrg SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, 16417104f784Smrg &dstBox, src_w, src_h, drw_w, drw_h); 16427104f784Smrg } 164309885543Smrg pPort->videoStatus = CLIENT_VIDEO_ON; 16447104f784Smrg 16457104f784Smrg LEAVE(Success); 164609885543Smrg 164709885543Smrg} 164809885543Smrg 164909885543Smrg 165009885543Smrgstatic int 165109885543SmrgSMI_QueryImageAttributes( 165209885543Smrg ScrnInfoPtr pScrn, 165309885543Smrg int id, 165409885543Smrg unsigned short *width, 165509885543Smrg unsigned short *height, 165609885543Smrg int *pitches, 165709885543Smrg int *offsets 165809885543Smrg) 165909885543Smrg{ 166009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 166109885543Smrg int size, tmp; 166209885543Smrg 16637104f784Smrg ENTER(); 166409885543Smrg 166509885543Smrg if (*width > pSmi->lcdWidth) { 166609885543Smrg *width = pSmi->lcdWidth; 166709885543Smrg } 166809885543Smrg if (*height > pSmi->lcdHeight) { 166909885543Smrg *height = pSmi->lcdHeight; 167009885543Smrg } 167109885543Smrg 167209885543Smrg *width = (*width + 1) & ~1; 167309885543Smrg if (offsets != NULL) { 167409885543Smrg offsets[0] = 0; 167509885543Smrg } 167609885543Smrg 167709885543Smrg switch (id) { 167809885543Smrg case FOURCC_YV12: 167909885543Smrg case FOURCC_I420: 168009885543Smrg *height = (*height + 1) & ~1; 168109885543Smrg size = (*width + 3) & ~3; 168209885543Smrg if (pitches != NULL) { 168309885543Smrg pitches[0] = size; 168409885543Smrg } 168509885543Smrg size *= *height; 168609885543Smrg if (offsets != NULL) { 168709885543Smrg offsets[1] = size; 168809885543Smrg } 168909885543Smrg tmp = ((*width >> 1) + 3) & ~3; 169009885543Smrg if (pitches != NULL) { 169109885543Smrg pitches[1] = pitches[2] = tmp; 169209885543Smrg } 169309885543Smrg tmp *= (*height >> 1); 169409885543Smrg size += tmp; 169509885543Smrg if (offsets != NULL) { 169609885543Smrg offsets[2] = size; 169709885543Smrg } 169809885543Smrg size += tmp; 169909885543Smrg break; 170009885543Smrg case FOURCC_YUY2: 170109885543Smrg case FOURCC_RV15: 170209885543Smrg case FOURCC_RV16: 170309885543Smrg default: 170409885543Smrg size = *width * 2; 170509885543Smrg if (pitches != NULL) { 170609885543Smrg pitches[0] = size; 170709885543Smrg } 170809885543Smrg size *= *height; 170909885543Smrg break; 171009885543Smrg case FOURCC_RV24: 171109885543Smrg size = *width * 3; 171209885543Smrg if (pitches != NULL) { 171309885543Smrg pitches[0] = size; 171409885543Smrg } 171509885543Smrg size *= *height; 171609885543Smrg break; 171709885543Smrg case FOURCC_RV32: 171809885543Smrg size = *width * 4; 171909885543Smrg if (pitches != NULL) { 172009885543Smrg pitches[0] = size; 172109885543Smrg } 172209885543Smrg size *= *height; 172309885543Smrg break; 172409885543Smrg } 172509885543Smrg 17267104f784Smrg LEAVE(size); 172709885543Smrg} 172809885543Smrg 172909885543Smrg 173009885543Smrg/******************************************************************************\ 173109885543Smrg** ** 173209885543Smrg** S U P P O R T F U N C T I O N S ** 173309885543Smrg** ** 173409885543Smrg\******************************************************************************/ 173509885543Smrg 173609885543Smrgstatic void 173709885543SmrgSMI_DisplayVideo( 173809885543Smrg ScrnInfoPtr pScrn, 173909885543Smrg int id, 174009885543Smrg int offset, 174109885543Smrg short width, 174209885543Smrg short height, 174309885543Smrg int pitch, 174409885543Smrg int x1, 174509885543Smrg int y1, 174609885543Smrg int x2, 174709885543Smrg int y2, 174809885543Smrg BoxPtr dstBox, 174909885543Smrg short vid_w, 175009885543Smrg short vid_h, 175109885543Smrg short drw_w, 175209885543Smrg short drw_h 175309885543Smrg) 175409885543Smrg{ 175509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 175609885543Smrg CARD32 vpr00; 1757e4f6584cSmrg uint32_t hstretch, vstretch; 175809885543Smrg 17597104f784Smrg ENTER(); 176009885543Smrg 176109885543Smrg vpr00 = READ_VPR(pSmi, 0x00) & ~0x0CB800FF; 176209885543Smrg 176309885543Smrg switch (id) { 176409885543Smrg case FOURCC_YV12: 176509885543Smrg case FOURCC_I420: 176609885543Smrg case FOURCC_YUY2: 176709885543Smrg vpr00 |= 0x6; 176809885543Smrg break; 176909885543Smrg case FOURCC_RV15: 177009885543Smrg vpr00 |= 0x1; 177109885543Smrg break; 177209885543Smrg case FOURCC_RV16: 177309885543Smrg vpr00 |= 0x2; 177409885543Smrg break; 177509885543Smrg case FOURCC_RV24: 177609885543Smrg vpr00 |= 0x4; 177709885543Smrg break; 177809885543Smrg case FOURCC_RV32: 177909885543Smrg vpr00 |= 0x3; 178009885543Smrg break; 178109885543Smrg } 178209885543Smrg 178309885543Smrg if (drw_w > vid_w) { 1784e4f6584cSmrg hstretch = ((uint32_t)(vid_w - 1) << 16) / (drw_w - 1); 178509885543Smrg } else { 178609885543Smrg hstretch = 0; 178709885543Smrg } 178809885543Smrg 178909885543Smrg if (drw_h > vid_h) { 1790e4f6584cSmrg vstretch = ((uint32_t)(vid_h - 1) << 16) / (drw_h - 1); 179109885543Smrg vpr00 |= 1 << 21; 179209885543Smrg } else { 179309885543Smrg vstretch = 0; 179409885543Smrg } 17957104f784Smrg 179609885543Smrg WRITE_VPR(pSmi, 0x00, vpr00 | (1 << 3) | (1 << 20)); 179709885543Smrg WRITE_VPR(pSmi, 0x14, (dstBox->x1) | (dstBox->y1 << 16)); 179809885543Smrg WRITE_VPR(pSmi, 0x18, (dstBox->x2) | (dstBox->y2 << 16)); 179909885543Smrg WRITE_VPR(pSmi, 0x1C, offset >> 3); 180009885543Smrg WRITE_VPR(pSmi, 0x20, (pitch >> 3) | ((pitch >> 3) << 16)); 1801e4f6584cSmrg WRITE_VPR(pSmi, 0x24, (hstretch & 0xff00) | ((vstretch & 0xff00) >> 8)); 1802e4f6584cSmrg if (pSmi->Chipset == SMI_LYNXEMplus) { /* This one can store additional precision */ 1803e4f6584cSmrg WRITE_VPR(pSmi, 0x68, ((hstretch & 0xff) << 8) | (vstretch & 0xff)); 1804e4f6584cSmrg } 180509885543Smrg 18067104f784Smrg LEAVE(); 18077104f784Smrg} 18087104f784Smrg 18097104f784Smrgstatic void 18107104f784SmrgSMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset, 18117104f784Smrg short width, short height, int pitch, 18127104f784Smrg int x1, int y1, int x2, int y2, BoxPtr dstBox, 18137104f784Smrg short vid_w, short vid_h, short drw_w, short drw_h, 18147104f784Smrg RegionPtr clipboxes) 18157104f784Smrg{ 18167104f784Smrg int32_t ScaleXn, ScaleXd, ScaleYn, ScaleYd; 18177104f784Smrg int32_t SrcTn, SrcTd, SrcLn, SrcLd; 18187104f784Smrg int32_t SrcRn, SrcBn; 18197104f784Smrg int32_t SrcDimX, SrcDimY; 18207104f784Smrg int32_t SrcYBase, SrcUBase, SrcVBase, SrcYPitch, SrcUVPitch; 18217104f784Smrg int32_t DestPitch; 18227104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 18237104f784Smrg BoxPtr pbox = REGION_RECTS(clipboxes); 18247104f784Smrg int i, nbox = REGION_NUM_RECTS(clipboxes); 18257104f784Smrg int32_t rect_x, rect_y, rect_w, rect_h, csc; 18267104f784Smrg float Hscale, Vscale; 18277104f784Smrg 18287104f784Smrg ENTER(); 18297104f784Smrg 18307104f784Smrg SrcYBase = offset; 18317104f784Smrg SrcYPitch = pitch; 18327104f784Smrg 18337104f784Smrg DestPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15; 18347104f784Smrg 18357104f784Smrg Hscale = (vid_w - 1) / (float)(drw_w - 1); 18367104f784Smrg ScaleXn = Hscale; 18377104f784Smrg ScaleXd = ((vid_w - 1) << 13) / (drw_w - 1) - (ScaleXn << 13); 18387104f784Smrg 18397104f784Smrg Vscale = (vid_h - 1) / (float)(drw_h - 1); 18407104f784Smrg ScaleYn = Vscale; 18417104f784Smrg ScaleYd = ((vid_h - 1) << 13) / (drw_h - 1) - (ScaleYn << 13); 18427104f784Smrg 18437104f784Smrg /* CSC constants */ 18447104f784Smrg WRITE_DPR(pSmi, 0xcc, 0); 18457104f784Smrg /* Use start of framebuffer as base offset */ 18467104f784Smrg WRITE_DPR(pSmi, 0xf8, 0); 18477104f784Smrg 18487104f784Smrg csc = (1 << 31) | (1 << 25); 18497104f784Smrg if (pSmi->Bpp > 2) 18507104f784Smrg csc |= 1 << 26; 18517104f784Smrg 18527104f784Smrg switch (id) { 18537104f784Smrg case FOURCC_YV12: 18547104f784Smrg SrcUVPitch = SrcYPitch / 2; 18557104f784Smrg SrcVBase = SrcYBase + SrcYPitch * height; 18567104f784Smrg SrcUBase = SrcVBase + SrcUVPitch * height / 2; 18577104f784Smrg csc |= 2 << 28; 18587104f784Smrg break; 18597104f784Smrg 18607104f784Smrg case FOURCC_I420: 18617104f784Smrg SrcUVPitch = SrcYPitch / 2; 18627104f784Smrg SrcUBase = SrcYBase + SrcYPitch * height; 18637104f784Smrg SrcVBase = SrcUBase + SrcUVPitch * height / 2; 18647104f784Smrg csc |= 2 << 28; 18657104f784Smrg break; 18667104f784Smrg 18677104f784Smrg case FOURCC_YUY2: 18687104f784Smrg case FOURCC_RV16: 18697104f784Smrg case FOURCC_RV32: 18707104f784Smrg SrcUBase = SrcVBase = SrcYBase; 18717104f784Smrg SrcUVPitch = SrcYPitch; 18727104f784Smrg break; 18737104f784Smrg 18747104f784Smrg default: 18757104f784Smrg LEAVE(); 18767104f784Smrg } 18777104f784Smrg 18787104f784Smrg WRITE_DPR(pSmi, 0xE4, ((SrcYPitch >> 4) << 16) | (SrcUVPitch >> 4)); 18797104f784Smrg WRITE_DPR(pSmi, 0xC8, SrcYBase); 18807104f784Smrg WRITE_DPR(pSmi, 0xD8, SrcUBase); 18817104f784Smrg WRITE_DPR(pSmi, 0xDC, SrcVBase); 18827104f784Smrg WRITE_DPR(pSmi, 0xF4, (((ScaleXn << 13) | ScaleXd) << 16) | 18837104f784Smrg (ScaleYn << 13 | ScaleYd)); 18847104f784Smrg 18857104f784Smrg for (i = 0; i < nbox; i++, pbox++) { 18867104f784Smrg rect_x = pbox->x1; 18877104f784Smrg rect_y = pbox->y1; 18887104f784Smrg rect_w = pbox->x2 - pbox->x1; 18897104f784Smrg rect_h = pbox->y2 - pbox->y1; 18907104f784Smrg 18917104f784Smrg SrcLn = (rect_x - dstBox->x1) * Hscale; 18927104f784Smrg SrcLd = ((rect_x - dstBox->x1) << 13) * Hscale - (SrcLn << 13); 18937104f784Smrg SrcRn = (rect_x + rect_w - dstBox->x1) * Hscale; 18947104f784Smrg 18957104f784Smrg SrcTn = (rect_y - dstBox->y1) * Vscale; 18967104f784Smrg SrcTd = ((rect_y - dstBox->y1) << 13) * Vscale - (SrcTn << 13); 18977104f784Smrg SrcBn = (rect_y + rect_h - dstBox->y1) * Vscale; 18987104f784Smrg 18997104f784Smrg SrcDimX = SrcRn - SrcLn + 2; 19007104f784Smrg SrcDimY = SrcBn - SrcTn + 2; 19017104f784Smrg 19027104f784Smrg WRITE_DPR(pSmi, 0xD0, (SrcLn << 16) | SrcLd); 19037104f784Smrg WRITE_DPR(pSmi, 0xD4, (SrcTn << 16) | SrcTd); 19047104f784Smrg WRITE_DPR(pSmi, 0xE0, (SrcDimX << 16) | SrcDimY); 19057104f784Smrg WRITE_DPR(pSmi, 0xE8, (rect_x << 16) | rect_y); 19067104f784Smrg WRITE_DPR(pSmi, 0xEC, (rect_w << 16) | rect_h); 19077104f784Smrg WRITE_DPR(pSmi, 0xF0, ((DestPitch >> 4) << 16) | rect_h); 19087104f784Smrg 19097104f784Smrg while (READ_DPR(pSmi, 0xfc) & (1 << 31)) 19107104f784Smrg ; 19117104f784Smrg WRITE_DPR(pSmi, 0xfc, csc); 19127104f784Smrg /* CSC stop */ 19137104f784Smrg while (READ_DPR(pSmi, 0xfc) & (1 << 31)) 19147104f784Smrg ; 19157104f784Smrg } 19167104f784Smrg 19177104f784Smrg LEAVE(); 19187104f784Smrg} 19197104f784Smrg 19207104f784Smrgstatic void 19217104f784SmrgSMI_DisplayVideo0501(ScrnInfoPtr pScrn, 19227104f784Smrg int id, 19237104f784Smrg int offset, 19247104f784Smrg short width, 19257104f784Smrg short height, 19267104f784Smrg int pitch, 19277104f784Smrg int x1, 19287104f784Smrg int y1, 19297104f784Smrg int x2, 19307104f784Smrg int y2, 19317104f784Smrg BoxPtr dstBox, 19327104f784Smrg short vid_w, short vid_h, short drw_w, short drw_h) 19337104f784Smrg{ 19347104f784Smrg SMIPtr pSmi = SMIPTR (pScrn); 19357104f784Smrg CARD32 dcr40; 19367104f784Smrg int hstretch, vstretch; 19377104f784Smrg 19387104f784Smrg ENTER(); 19397104f784Smrg 19407104f784Smrg dcr40 = READ_DCR(pSmi, 0x0040) & ~0x00003FFF; 19417104f784Smrg 19427104f784Smrg switch (id) { 19437104f784Smrg case FOURCC_YV12: 19447104f784Smrg case FOURCC_I420: 19457104f784Smrg case FOURCC_YUY2: 19467104f784Smrg dcr40 |= 0x3; 19477104f784Smrg break; 19487104f784Smrg 19497104f784Smrg case FOURCC_RV16: 19507104f784Smrg dcr40 |= 0x1; 19517104f784Smrg break; 19527104f784Smrg 19537104f784Smrg case FOURCC_RV32: 19547104f784Smrg dcr40 |= 0x2; 19557104f784Smrg break; 19567104f784Smrg } 19577104f784Smrg 19587104f784Smrg if (drw_w > vid_w) { /* Horizontal Stretch */ 19597104f784Smrg hstretch = 4096 * vid_w / drw_w; 19607104f784Smrg dcr40 |= 1 << 8; 19617104f784Smrg } 19627104f784Smrg else { /* Horizontal Shrink */ 19637104f784Smrg if (drw_w < (vid_w >> 1)) 19647104f784Smrg drw_w = vid_w >> 1; 19657104f784Smrg hstretch = (4096 * drw_w / vid_w) | 0x8000; 19667104f784Smrg } 19677104f784Smrg 19687104f784Smrg if (drw_h > vid_h) { /* Vertical Stretch */ 19697104f784Smrg vstretch = 4096 * vid_h / drw_h; 19707104f784Smrg dcr40 |= 1 << 9; 19717104f784Smrg } 19727104f784Smrg else { /* Vertical Shrink */ 19737104f784Smrg if (drw_h < (vid_h >> 1)) 19747104f784Smrg drw_h = vid_h >> 1; 19757104f784Smrg vstretch = (4096 * drw_h / vid_h) | 0x8000; 19767104f784Smrg } 19777104f784Smrg 19787104f784Smrg /* Set Color Key Enable bit */ 19797104f784Smrg 19807104f784Smrg WRITE_DCR(pSmi, 0x0000, READ_DCR(pSmi, 0x0000) | (1 << 9)); 19817104f784Smrg WRITE_DCR(pSmi, 0x0050, dstBox->x1 | (dstBox->y1 << 16)); 19827104f784Smrg WRITE_DCR(pSmi, 0x0054, dstBox->x2 | (dstBox->y2 << 16)); 19837104f784Smrg WRITE_DCR(pSmi, 0x0044, offset); 19847104f784Smrg 19857104f784Smrg WRITE_DCR(pSmi, 0x0048, pitch | (pitch << 16)); 19867104f784Smrg WRITE_DCR(pSmi, 0x004C, offset + (pitch * height)); 19877104f784Smrg WRITE_DCR(pSmi, 0x0058, (vstretch << 16) | hstretch); 19887104f784Smrg WRITE_DCR(pSmi, 0x005C, 0x00000000); 19897104f784Smrg WRITE_DCR(pSmi, 0x0060, 0x00EDEDED); 19907104f784Smrg 19917104f784Smrg WRITE_DCR(pSmi, 0x0040, dcr40 | (1 << 2)); 19927104f784Smrg 19937104f784Smrg LEAVE(); 199409885543Smrg} 199509885543Smrg 199609885543Smrgstatic void 199709885543SmrgSMI_DisplayVideo0730( 199809885543Smrg ScrnInfoPtr pScrn, 199909885543Smrg int id, 200009885543Smrg int offset, 200109885543Smrg short width, 200209885543Smrg short height, 200309885543Smrg int pitch, 200409885543Smrg int x1, 200509885543Smrg int y1, 200609885543Smrg int x2, 200709885543Smrg int y2, 200809885543Smrg BoxPtr dstBox, 200909885543Smrg short vid_w, 201009885543Smrg short vid_h, 201109885543Smrg short drw_w, 201209885543Smrg short drw_h 201309885543Smrg) 201409885543Smrg{ 201509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 201609885543Smrg CARD32 fpr00; 201709885543Smrg int hstretch, vstretch; 201809885543Smrg 20197104f784Smrg ENTER(); 202009885543Smrg 202109885543Smrg fpr00 = READ_FPR(pSmi, 0x00) & ~(FPR00_MASKBITS); 202209885543Smrg 202309885543Smrg switch (id) { 202409885543Smrg case FOURCC_YV12: 202509885543Smrg case FOURCC_I420: 202609885543Smrg case FOURCC_YUY2: 202709885543Smrg fpr00 |= FPR00_FMT_YUV422; 202809885543Smrg break; 202909885543Smrg case FOURCC_RV15: 203009885543Smrg fpr00 |= FPR00_FMT_15P; 203109885543Smrg break; 203209885543Smrg case FOURCC_RV16: 203309885543Smrg fpr00 |= FPR00_FMT_16P; 203409885543Smrg break; 203509885543Smrg case FOURCC_RV24: 203609885543Smrg fpr00 |= FPR00_FMT_24P; 203709885543Smrg break; 203809885543Smrg case FOURCC_RV32: 203909885543Smrg fpr00 |= FPR00_FMT_32P; 204009885543Smrg break; 204109885543Smrg } 204209885543Smrg 204309885543Smrg /* the formulas for calculating the stretch values do not match the 204409885543Smrg documentation, but they're the same as the ddraw driver and they work */ 204509885543Smrg if (drw_w > vid_w) { 204609885543Smrg hstretch = (8192 * vid_w / drw_w); 204709885543Smrg } else { 204809885543Smrg hstretch = 0; 204909885543Smrg } 205009885543Smrg 205109885543Smrg if (drw_h > vid_h) { 205209885543Smrg vstretch = (8192 * vid_h / drw_h); 205309885543Smrg } else { 205409885543Smrg vstretch = 0; 205509885543Smrg } 205609885543Smrg 205709885543Smrg WRITE_FPR(pSmi, FPR00, fpr00 | FPR00_VWIENABLE | FPR00_VWIKEYENABLE); 205809885543Smrg WRITE_FPR(pSmi, FPR14, (dstBox->x1) | (dstBox->y1 << 16)); 205909885543Smrg WRITE_FPR(pSmi, FPR18, (dstBox->x2) | (dstBox->y2 << 16)); 206009885543Smrg WRITE_FPR(pSmi, FPR1C, offset >> 3); 206109885543Smrg WRITE_FPR(pSmi, FPR20, (pitch >> 3) | ((pitch >> 3) << 16)); 206209885543Smrg WRITE_FPR(pSmi, FPR24, (hstretch & 0xFF00) | ((vstretch & 0xFF00)>>8)); 206309885543Smrg WRITE_FPR(pSmi, FPR68, ((hstretch & 0x00FF)<<8) | (vstretch & 0x00FF)); 206409885543Smrg 20657104f784Smrg LEAVE(); 206609885543Smrg} 206709885543Smrg 206809885543Smrgstatic void 2069b12e5c03SmrgSMI_BlockHandler(BLOCKHANDLER_ARGS_DECL) 207009885543Smrg{ 2071b12e5c03Smrg SCREEN_PTR(arg); 2072b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 207309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 207409885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 207509885543Smrg 207609885543Smrg pScreen->BlockHandler = pSmi->BlockHandler; 2077b12e5c03Smrg (*pScreen->BlockHandler)(BLOCKHANDLER_ARGS); 207809885543Smrg pScreen->BlockHandler = SMI_BlockHandler; 207909885543Smrg 208009885543Smrg if (pPort->videoStatus & TIMER_MASK) { 208109885543Smrg UpdateCurrentTime(); 208209885543Smrg if (pPort->videoStatus & OFF_TIMER) { 208309885543Smrg if (pPort->offTime < currentTime.milliseconds) { 208409885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 208509885543Smrg WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); 208609885543Smrg } 20877104f784Smrg else if (IS_MSOC(pSmi)) 20887104f784Smrg WRITE_DCR(pSmi, 0x0040, READ_DCR(pSmi, 0x0040) & ~0x00000004); 20897104f784Smrg else 20907104f784Smrg WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); 209109885543Smrg pPort->videoStatus = FREE_TIMER; 209209885543Smrg pPort->freeTime = currentTime.milliseconds + FREE_DELAY; 209309885543Smrg } 209409885543Smrg } else { 209509885543Smrg if (pPort->freeTime < currentTime.milliseconds) { 209609885543Smrg SMI_FreeMemory(pScrn, pPort->video_memory); 209709885543Smrg pPort->video_memory = NULL; 209809885543Smrg } 209909885543Smrg pPort->videoStatus = 0; 210009885543Smrg } 210109885543Smrg } 210209885543Smrg} 210309885543Smrg 210409885543Smrg#if 0 210509885543Smrgstatic int 210609885543SmrgSMI_SendI2C( 210709885543Smrg ScrnInfoPtr pScrn, 210809885543Smrg CARD8 device, 210909885543Smrg char *devName, 211009885543Smrg SMI_I2CDataPtr i2cData 211109885543Smrg) 211209885543Smrg{ 21137104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 21147104f784Smrg I2CDevPtr dev; 21157104f784Smrg int status = Success; 211609885543Smrg 21177104f784Smrg ENTER(); 211809885543Smrg 21197104f784Smrg if (pSmi->I2C == NULL) 21207104f784Smrg LEAVE(BadAlloc); 212109885543Smrg 21227104f784Smrg dev = xf86CreateI2CDevRec(); 21237104f784Smrg if (dev == NULL) 21247104f784Smrg LEAVE(BadAlloc); 212509885543Smrg 21267104f784Smrg dev->DevName = devName; 21277104f784Smrg dev->SlaveAddr = device; 21287104f784Smrg dev->pI2CBus = pSmi->I2C; 21297104f784Smrg 21307104f784Smrg if (!xf86I2CDevInit(dev)) 21317104f784Smrg status = BadAlloc; 21327104f784Smrg else { 21337104f784Smrg while (i2cData->address != 0xFF || i2cData->data != 0xFF) { /* PDR#676 */ 21347104f784Smrg if (!xf86I2CWriteByte(dev, i2cData->address, i2cData->data)) { 213509885543Smrg status = BadAlloc; 21367104f784Smrg break; 21377104f784Smrg } 21387104f784Smrg i2cData++; 213909885543Smrg } 21407104f784Smrg } 214109885543Smrg 21427104f784Smrg xf86DestroyI2CDevRec(dev, TRUE); 21437104f784Smrg 21447104f784Smrg LEAVE(status); 214509885543Smrg} 214609885543Smrg#endif 214709885543Smrg 214809885543Smrg/******************************************************************************\ 214909885543Smrg** ** 215009885543Smrg** O F F S C R E E N M E M O R Y M A N A G E R ** 215109885543Smrg** ** 215209885543Smrg\******************************************************************************/ 215309885543Smrg 215409885543Smrgstatic void 215509885543SmrgSMI_InitOffscreenImages( 215609885543Smrg ScreenPtr pScreen 215709885543Smrg) 215809885543Smrg{ 215909885543Smrg XF86OffscreenImagePtr offscreenImages; 2160b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 216109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 216209885543Smrg SMI_PortPtr pPort = (SMI_PortPtr) pSmi->ptrAdaptor->pPortPrivates[0].ptr; 216309885543Smrg 21647104f784Smrg ENTER(); 216509885543Smrg 21667b58d2e0Smrg offscreenImages = malloc(sizeof(XF86OffscreenImageRec)); 216709885543Smrg if (offscreenImages == NULL) { 21687104f784Smrg LEAVE(); 216909885543Smrg } 217009885543Smrg 217109885543Smrg offscreenImages->image = SMI_VideoImages; 21727104f784Smrg offscreenImages->flags = VIDEO_OVERLAID_IMAGES; 21737104f784Smrg if (IS_MSOC(pSmi)) 21747104f784Smrg offscreenImages->flags |= VIDEO_CLIP_TO_VIEWPORT; 217509885543Smrg offscreenImages->alloc_surface = SMI_AllocSurface; 217609885543Smrg offscreenImages->free_surface = SMI_FreeSurface; 217709885543Smrg offscreenImages->display = SMI_DisplaySurface; 217809885543Smrg offscreenImages->stop = SMI_StopSurface; 217909885543Smrg offscreenImages->getAttribute = SMI_GetSurfaceAttribute; 218009885543Smrg offscreenImages->setAttribute = SMI_SetSurfaceAttribute; 218109885543Smrg offscreenImages->max_width = pSmi->lcdWidth; 218209885543Smrg offscreenImages->max_height = pSmi->lcdHeight; 218309885543Smrg if (!pPort->I2CDev.SlaveAddr) { 218409885543Smrg offscreenImages->num_attributes = nElems(SMI_VideoAttributes); 218509885543Smrg offscreenImages->attributes = SMI_VideoAttributes; 218609885543Smrg } else { 218709885543Smrg offscreenImages->num_attributes = nElems(SMI_VideoAttributesSAA711x); 218809885543Smrg offscreenImages->attributes = SMI_VideoAttributesSAA711x; 218909885543Smrg } 219009885543Smrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 219109885543Smrg 21927104f784Smrg LEAVE(); 219309885543Smrg} 219409885543Smrg 219509885543Smrgstatic void 219609885543SmrgSMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) 219709885543Smrg{ 2198b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 219909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 220009885543Smrg SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr; 220109885543Smrg 22027104f784Smrg ENTER(); 220309885543Smrg 220409885543Smrg if (pPort->video_memory == area) 220509885543Smrg pPort->video_memory = NULL; 220609885543Smrg 22077104f784Smrg LEAVE(); 220809885543Smrg} 220909885543Smrg 22107104f784SmrgCARD32 22117104f784SmrgSMI_AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size) 221209885543Smrg{ 2213b12e5c03Smrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 22147104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 22157104f784Smrg int offset = 0; 221609885543Smrg 22177104f784Smrg ENTER(); 221809885543Smrg 221909885543Smrg if (pSmi->useEXA) { 222009885543Smrg ExaOffscreenArea *area = *mem_struct; 222109885543Smrg 222209885543Smrg if (area != NULL) { 222309885543Smrg if (area->size >= size) 22247104f784Smrg LEAVE(area->offset); 222509885543Smrg 222609885543Smrg exaOffscreenFree(pScrn->pScreen, area); 222709885543Smrg } 222809885543Smrg 22297104f784Smrg area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, 22307104f784Smrg SMI_VideoSave, NULL); 223109885543Smrg 223209885543Smrg *mem_struct = area; 22337104f784Smrg if (area != NULL) 22347104f784Smrg offset = area->offset; 22357104f784Smrg } 22367104f784Smrg else { 22377104f784Smrg FBLinearPtr linear = *mem_struct; 223809885543Smrg 223909885543Smrg /* XAA allocates in units of pixels at the screen bpp, 224009885543Smrg * so adjust size appropriately. 224109885543Smrg */ 224209885543Smrg size = (size + pSmi->Bpp - 1) / pSmi->Bpp; 224309885543Smrg 224409885543Smrg if (linear) { 224509885543Smrg if (linear->size >= size) 22467104f784Smrg LEAVE(linear->offset * pSmi->Bpp); 224709885543Smrg 224809885543Smrg if (xf86ResizeOffscreenLinear(linear, size)) 22497104f784Smrg LEAVE(linear->offset * pSmi->Bpp); 225009885543Smrg 22517104f784Smrg xf86FreeOffscreenLinear(linear); 22527104f784Smrg } 22537104f784Smrg else { 22547104f784Smrg int max_size; 225509885543Smrg 22567104f784Smrg xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, 22577104f784Smrg PRIORITY_EXTREME); 22587104f784Smrg if (max_size < size) 22597104f784Smrg LEAVE(0); 226009885543Smrg 22617104f784Smrg xf86PurgeUnlockedOffscreenAreas(pScreen); 226209885543Smrg } 226309885543Smrg 22647104f784Smrg linear = xf86AllocateOffscreenLinear(pScreen, size, 16, 22657104f784Smrg NULL, NULL, NULL); 22667104f784Smrg if ((*mem_struct = linear) != NULL) 22677104f784Smrg offset = linear->offset * pSmi->Bpp; 22687104f784Smrg 22697104f784Smrg DEBUG("offset = %p\n", offset); 227009885543Smrg } 227109885543Smrg 22727104f784Smrg LEAVE(offset); 227309885543Smrg} 227409885543Smrg 22757104f784Smrgvoid 227609885543SmrgSMI_FreeMemory( 227709885543Smrg ScrnInfoPtr pScrn, 227809885543Smrg void *mem_struct 227909885543Smrg) 228009885543Smrg{ 228109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 228209885543Smrg 22837104f784Smrg ENTER(); 228409885543Smrg 228509885543Smrg if (pSmi->useEXA) { 228609885543Smrg ExaOffscreenArea *area = mem_struct; 228709885543Smrg 228809885543Smrg if (area != NULL) 228909885543Smrg exaOffscreenFree(pScrn->pScreen, area); 229009885543Smrg } else { 229109885543Smrg FBLinearPtr linear = mem_struct; 229209885543Smrg 229309885543Smrg if (linear != NULL) 229409885543Smrg xf86FreeOffscreenLinear(linear); 229509885543Smrg } 229609885543Smrg 22977104f784Smrg LEAVE(); 22987104f784Smrg} 22997104f784Smrg 23007104f784Smrgstatic void 23017104f784SmrgCopyYV12ToVideoMem(unsigned char *src1, unsigned char *src2, 23027104f784Smrg unsigned char *src3, unsigned char *dst, 23037104f784Smrg int src1Pitch, int src23Pitch, int dstPitch, 23047104f784Smrg int height, int width) 23057104f784Smrg{ 23067104f784Smrg int j = height; 23077104f784Smrg 23087104f784Smrg ENTER(); 23097104f784Smrg 23107104f784Smrg /* copy 1 data */ 23117104f784Smrg while (j -- > 0) { 23127104f784Smrg memcpy(dst, src1, width); 23137104f784Smrg src1 += src1Pitch; 23147104f784Smrg dst += dstPitch; 23157104f784Smrg } 23167104f784Smrg /* copy 2 data */ 23177104f784Smrg j = height / 2; 23187104f784Smrg while (j -- > 0) { 23197104f784Smrg memcpy(dst, src2, width / 2); 23207104f784Smrg src2 += src23Pitch; 23217104f784Smrg dst += dstPitch / 2; 23227104f784Smrg } 23237104f784Smrg /* copy 3 data */ 23247104f784Smrg j = height / 2; 23257104f784Smrg while (j -- > 0) { 23267104f784Smrg memcpy(dst, src3, width / 2); 23277104f784Smrg src3 += src23Pitch; 23287104f784Smrg dst += dstPitch / 2; 23297104f784Smrg } 23307104f784Smrg 23317104f784Smrg LEAVE(); 233209885543Smrg} 233309885543Smrg 233409885543Smrgstatic int 233509885543SmrgSMI_AllocSurface( 233609885543Smrg ScrnInfoPtr pScrn, 233709885543Smrg int id, 233809885543Smrg unsigned short width, 233909885543Smrg unsigned short height, 234009885543Smrg XF86SurfacePtr surface 234109885543Smrg) 234209885543Smrg{ 234309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 234409885543Smrg int pitch, bpp, offset, size; 234509885543Smrg void *surface_memory = NULL; 234609885543Smrg SMI_OffscreenPtr ptrOffscreen; 234709885543Smrg 23487104f784Smrg ENTER(); 234909885543Smrg 23507104f784Smrg if (width > pSmi->lcdWidth || height > pSmi->lcdHeight) 23517104f784Smrg LEAVE(BadAlloc); 235209885543Smrg 235309885543Smrg switch (id) { 235409885543Smrg case FOURCC_YV12: 235509885543Smrg case FOURCC_I420: 235609885543Smrg case FOURCC_YUY2: 235709885543Smrg case FOURCC_RV15: 235809885543Smrg case FOURCC_RV16: 235909885543Smrg bpp = 2; 236009885543Smrg break; 236109885543Smrg case FOURCC_RV24: 236209885543Smrg bpp = 3; 236309885543Smrg break; 236409885543Smrg case FOURCC_RV32: 236509885543Smrg bpp = 4; 236609885543Smrg break; 236709885543Smrg default: 23687104f784Smrg LEAVE(BadAlloc); 236909885543Smrg } 237009885543Smrg 237109885543Smrg width = (width + 1) & ~1; 237209885543Smrg pitch = (width * bpp + 15) & ~15; 237309885543Smrg size = pitch * height; 237409885543Smrg 237509885543Smrg offset = SMI_AllocateMemory(pScrn, &surface_memory, size); 23767104f784Smrg if (offset == 0) 23777104f784Smrg LEAVE(BadAlloc); 237809885543Smrg 23797b58d2e0Smrg surface->pitches = malloc(sizeof(int)); 238009885543Smrg if (surface->pitches == NULL) { 238109885543Smrg SMI_FreeMemory(pScrn, surface_memory); 23827104f784Smrg LEAVE(BadAlloc); 238309885543Smrg } 23847b58d2e0Smrg surface->offsets = malloc(sizeof(int)); 238509885543Smrg if (surface->offsets == NULL) { 23867b58d2e0Smrg free(surface->pitches); 238709885543Smrg SMI_FreeMemory(pScrn, surface_memory); 23887104f784Smrg LEAVE(BadAlloc); 238909885543Smrg } 239009885543Smrg 23917b58d2e0Smrg ptrOffscreen = malloc(sizeof(SMI_OffscreenRec)); 239209885543Smrg if (ptrOffscreen == NULL) { 23937b58d2e0Smrg free(surface->offsets); 23947b58d2e0Smrg free(surface->pitches); 239509885543Smrg SMI_FreeMemory(pScrn, surface_memory); 23967104f784Smrg LEAVE(BadAlloc); 239709885543Smrg } 239809885543Smrg 239909885543Smrg surface->pScrn = pScrn; 240009885543Smrg surface->id = id; 240109885543Smrg surface->width = width; 240209885543Smrg surface->height = height; 240309885543Smrg surface->pitches[0] = pitch; 240409885543Smrg surface->offsets[0] = offset; 240509885543Smrg surface->devPrivate.ptr = (pointer) ptrOffscreen; 240609885543Smrg 240709885543Smrg ptrOffscreen->surface_memory = surface_memory; 240809885543Smrg ptrOffscreen->isOn = FALSE; 240909885543Smrg 24107104f784Smrg LEAVE(Success); 241109885543Smrg} 241209885543Smrg 241309885543Smrgstatic int 241409885543SmrgSMI_FreeSurface( 241509885543Smrg XF86SurfacePtr surface 241609885543Smrg) 241709885543Smrg{ 241809885543Smrg ScrnInfoPtr pScrn = surface->pScrn; 241909885543Smrg SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr; 242009885543Smrg 24217104f784Smrg ENTER(); 242209885543Smrg 242309885543Smrg if (ptrOffscreen->isOn) { 242409885543Smrg SMI_StopSurface(surface); 242509885543Smrg } 242609885543Smrg 242709885543Smrg SMI_FreeMemory(pScrn, ptrOffscreen->surface_memory); 24287b58d2e0Smrg free(surface->pitches); 24297b58d2e0Smrg free(surface->offsets); 24307b58d2e0Smrg free(surface->devPrivate.ptr); 243109885543Smrg 24327104f784Smrg LEAVE(Success); 243309885543Smrg} 243409885543Smrg 243509885543Smrgstatic int 243609885543SmrgSMI_DisplaySurface( 243709885543Smrg XF86SurfacePtr surface, 243809885543Smrg short vid_x, 243909885543Smrg short vid_y, 244009885543Smrg short drw_x, 244109885543Smrg short drw_y, 244209885543Smrg short vid_w, 244309885543Smrg short vid_h, 244409885543Smrg short drw_w, 244509885543Smrg short drw_h, 244609885543Smrg RegionPtr clipBoxes 244709885543Smrg) 244809885543Smrg{ 244909885543Smrg SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr; 245009885543Smrg SMIPtr pSmi = SMIPTR(surface->pScrn); 245109885543Smrg SMI_PortPtr pPort = pSmi->ptrAdaptor->pPortPrivates[0].ptr; 245209885543Smrg INT32 x1, y1, x2, y2; 245309885543Smrg BoxRec dstBox; 24547104f784Smrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(surface->pScrn); 24557104f784Smrg xf86CrtcPtr crtc; 245609885543Smrg 24577104f784Smrg ENTER(); 245809885543Smrg 245909885543Smrg x1 = vid_x; 246009885543Smrg x2 = vid_x + vid_w; 246109885543Smrg y1 = vid_y; 246209885543Smrg y2 = vid_y + vid_h; 246309885543Smrg 246409885543Smrg dstBox.x1 = drw_x; 246509885543Smrg dstBox.x2 = drw_x + drw_w; 246609885543Smrg dstBox.y1 = drw_y; 246709885543Smrg dstBox.y2 = drw_y + drw_h; 246809885543Smrg 24697104f784Smrg if(!xf86_crtc_clip_video_helper(surface->pScrn, &crtc, crtcConf->crtc[0], &dstBox, 24707104f784Smrg &x1, &x2, &y1, &y2, clipBoxes, surface->width, surface->height)) 24717104f784Smrg LEAVE(Success); 247209885543Smrg 24737b58d2e0Smrg if (!crtc) 24747b58d2e0Smrg LEAVE(Success); 24757b58d2e0Smrg 24767104f784Smrg /* Transform dstBox to the CRTC coordinates */ 24777104f784Smrg dstBox.x1 -= crtc->x; 24787104f784Smrg dstBox.y1 -= crtc->y; 24797104f784Smrg dstBox.x2 -= crtc->x; 24807104f784Smrg dstBox.y2 -= crtc->y; 248109885543Smrg 248209885543Smrg xf86XVFillKeyHelper(surface->pScrn->pScreen, 248309885543Smrg pPort->Attribute[XV_COLORKEY], clipBoxes); 24847104f784Smrg SMI_ResetVideo(surface->pScrn); 248509885543Smrg 24867104f784Smrg if (pSmi->Chipset == SMI_COUGAR3DR) 248709885543Smrg SMI_DisplayVideo0730(surface->pScrn, surface->id, surface->offsets[0], 248809885543Smrg surface->width, surface->height, surface->pitches[0], x1, y1, x2, 248909885543Smrg y2, &dstBox, vid_w, vid_h, drw_w, drw_h); 24907104f784Smrg else if (IS_MSOC(pSmi)) 24917104f784Smrg SMI_DisplayVideo0501(surface->pScrn, surface->id, 24927104f784Smrg surface->offsets[0], surface->width, 24937104f784Smrg surface->height, surface->pitches[0], x1, y1, 24947104f784Smrg x2, y2, &dstBox, vid_w, vid_h, drw_w, drw_h); 24957104f784Smrg else{ 24967104f784Smrg if(crtc == crtcConf->crtc[0]) 24977104f784Smrg SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0], 24987104f784Smrg surface->width, surface->height, surface->pitches[0], x1, y1, x2, 24997104f784Smrg y2, &dstBox, vid_w, vid_h, drw_w, drw_h); 250009885543Smrg } 250109885543Smrg 250209885543Smrg ptrOffscreen->isOn = TRUE; 250309885543Smrg if (pPort->videoStatus & CLIENT_VIDEO_ON) { 250409885543Smrg REGION_EMPTY(surface->pScrn->pScreen, &pPort->clip); 250509885543Smrg UpdateCurrentTime(); 250609885543Smrg pPort->videoStatus = FREE_TIMER; 250709885543Smrg pPort->freeTime = currentTime.milliseconds + FREE_DELAY; 250809885543Smrg } 250909885543Smrg 25107104f784Smrg LEAVE(Success); 251109885543Smrg} 251209885543Smrg 251309885543Smrgstatic int 251409885543SmrgSMI_StopSurface( 251509885543Smrg XF86SurfacePtr surface 251609885543Smrg) 251709885543Smrg{ 251809885543Smrg SMI_OffscreenPtr ptrOffscreen = (SMI_OffscreenPtr) surface->devPrivate.ptr; 251909885543Smrg 25207104f784Smrg ENTER(); 252109885543Smrg 252209885543Smrg if (ptrOffscreen->isOn) { 252309885543Smrg SMIPtr pSmi = SMIPTR(surface->pScrn); 252409885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 252509885543Smrg WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); 252609885543Smrg } else { 252709885543Smrg WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); 252809885543Smrg } 252909885543Smrg 253009885543Smrg ptrOffscreen->isOn = FALSE; 253109885543Smrg } 253209885543Smrg 25337104f784Smrg LEAVE(Success); 253409885543Smrg} 253509885543Smrg 253609885543Smrgstatic int 253709885543SmrgSMI_GetSurfaceAttribute( 253809885543Smrg ScrnInfoPtr pScrn, 253909885543Smrg Atom attr, 254009885543Smrg INT32 *value 254109885543Smrg) 254209885543Smrg{ 254309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 254409885543Smrg 254509885543Smrg return SMI_GetPortAttribute(pScrn, attr, value, 254609885543Smrg (pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr); 254709885543Smrg} 254809885543Smrg 254909885543Smrgstatic int 255009885543SmrgSMI_SetSurfaceAttribute( 255109885543Smrg ScrnInfoPtr pScrn, 255209885543Smrg Atom attr, 255309885543Smrg INT32 value 255409885543Smrg) 255509885543Smrg{ 255609885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 255709885543Smrg 255809885543Smrg return SMI_SetPortAttribute(pScrn, attr, value, 255909885543Smrg (pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr); 256009885543Smrg} 256109885543Smrg 256209885543Smrgstatic void 256309885543SmrgSetKeyReg(SMIPtr pSmi, int reg, int value) 256409885543Smrg{ 25657104f784Smrg if (pSmi->Chipset == SMI_COUGAR3DR) 256609885543Smrg WRITE_FPR(pSmi, reg, value); 25677104f784Smrg else if (IS_MSOC(pSmi)) { 25687104f784Smrg /* We don't change the color mask, and we don't do brightness. IF 25697104f784Smrg * they write to the colorkey register, we'll write the value to the 25707104f784Smrg * 501 colorkey register */ 25717104f784Smrg if (FPR04 == reg) /* Only act on colorkey value writes */ 25727104f784Smrg WRITE_DCR(pSmi, 0x0008, value);/* ColorKey register is DCR08 */ 257309885543Smrg } 25747104f784Smrg else 25757104f784Smrg WRITE_VPR(pSmi, reg, value); 257609885543Smrg} 257709885543Smrg 257809885543Smrg#else /* SMI_USE_VIDEO */ 257909885543Smrgvoid SMI_InitVideo(ScreenPtr pScreen) {} 258009885543Smrg#endif 2581