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