172b676d7Smrg/* 272b676d7Smrg * Xv driver for SiS 5597/5598, 6326 and 530/620. 372b676d7Smrg * 472b676d7Smrg * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria. 572b676d7Smrg * 672b676d7Smrg * Redistribution and use in source and binary forms, with or without 772b676d7Smrg * modification, are permitted provided that the following conditions 872b676d7Smrg * are met: 972b676d7Smrg * 1) Redistributions of source code must retain the above copyright 1072b676d7Smrg * notice, this list of conditions and the following disclaimer. 1172b676d7Smrg * 2) Redistributions in binary form must reproduce the above copyright 1272b676d7Smrg * notice, this list of conditions and the following disclaimer in the 1372b676d7Smrg * documentation and/or other materials provided with the distribution. 1472b676d7Smrg * 3) The name of the author may not be used to endorse or promote products 1572b676d7Smrg * derived from this software without specific prior written permission. 1672b676d7Smrg * 1772b676d7Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1872b676d7Smrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1972b676d7Smrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2072b676d7Smrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2172b676d7Smrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2272b676d7Smrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2372b676d7Smrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2472b676d7Smrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2572b676d7Smrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2672b676d7Smrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2772b676d7Smrg * 2872b676d7Smrg * Author: Thomas Winischhofer <thomas@winischhofer.net> 2972b676d7Smrg * 3072b676d7Smrg */ 3172b676d7Smrg 3272b676d7Smrg#ifdef HAVE_CONFIG_H 3372b676d7Smrg#include "config.h" 3472b676d7Smrg#endif 3572b676d7Smrg 3672b676d7Smrg#include "sis.h" 3772b676d7Smrg 3872b676d7Smrg#ifdef SIS_USE_XAA 3972b676d7Smrg#include "xf86fbman.h" 4072b676d7Smrg#endif 4172b676d7Smrg#include "xf86xv.h" 4272b676d7Smrg#include "regionstr.h" 4372b676d7Smrg#include <X11/extensions/Xv.h> 4472b676d7Smrg#include "dixstruct.h" 4572b676d7Smrg#include "fourcc.h" 4672b676d7Smrg 4772b676d7Smrg#define SIS_NEED_inSISREG 4872b676d7Smrg#define SIS_NEED_outSISREG 4972b676d7Smrg#define SIS_NEED_inSISIDXREG 5072b676d7Smrg#define SIS_NEED_outSISIDXREG 5172b676d7Smrg#define SIS_NEED_setSISIDXREGmask 5272b676d7Smrg#include "sis_regs.h" 5372b676d7Smrg 5472b676d7Smrg#define OFF_DELAY 200 /* milliseconds */ 5572b676d7Smrg#define FREE_DELAY 60000 5672b676d7Smrg 5772b676d7Smrg#define OFF_TIMER 0x01 5872b676d7Smrg#define FREE_TIMER 0x02 5972b676d7Smrg#define CLIENT_VIDEO_ON 0x04 6072b676d7Smrg 6172b676d7Smrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 6272b676d7Smrg 6372b676d7Smrg#define WATCHDOG_DELAY 500000 /* Watchdog counter for Vertical Restrace waiting */ 6472b676d7Smrg 6572b676d7Smrgstatic XF86VideoAdaptorPtr SIS6326SetupImageVideo(ScreenPtr); 6672b676d7Smrgstatic void SIS6326StopVideo(ScrnInfoPtr, pointer, Bool); 6772b676d7Smrgstatic int SIS6326SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 6872b676d7Smrgstatic int SIS6326GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 6972b676d7Smrgstatic void SIS6326QueryBestSize(ScrnInfoPtr, Bool, short, short, short, 7072b676d7Smrg short, unsigned int *,unsigned int *, pointer); 7172b676d7Smrgstatic int SIS6326PutImage( ScrnInfoPtr, 7272b676d7Smrg short, short, short, short, short, short, short, short, 7372b676d7Smrg int, unsigned char*, short, short, Bool, RegionPtr, pointer, 7472b676d7Smrg DrawablePtr); 7572b676d7Smrgstatic int SIS6326QueryImageAttributes(ScrnInfoPtr, 7672b676d7Smrg int, unsigned short *, unsigned short *, int *, int *); 7772b676d7Smrgstatic void SIS6326VideoTimerCallback(ScrnInfoPtr pScrn, Time now); 7872b676d7Smrgstatic void SIS6326InitOffscreenImages(ScreenPtr pScrn); 7972b676d7Smrg 8072b676d7Smrgextern unsigned int SISAllocateFBMemory(ScrnInfoPtr pScrn, void **handle, int bytesize); 8172b676d7Smrgextern void SISFreeFBMemory(ScrnInfoPtr pScrn, void **handle); 8272b676d7Smrg 8372b676d7Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 8472b676d7Smrg 8572b676d7Smrgstatic Atom xvBrightness, xvContrast, xvColorKey; 8672b676d7Smrgstatic Atom xvAutopaintColorKey, xvSetDefaults; 8772b676d7Smrgstatic Atom xvDisableGfx; 8872b676d7Smrg 8972b676d7Smrg#define IMAGE_MIN_WIDTH 32 /* Minimum and maximum image sizes */ 9072b676d7Smrg#define IMAGE_MIN_HEIGHT 24 9172b676d7Smrg#define IMAGE_MAX_WIDTH 720 /* Are these correct for the chips ? */ 9272b676d7Smrg#define IMAGE_MAX_HEIGHT 576 9372b676d7Smrg#define IMAGE_MAX_WIDTH_5597 384 9472b676d7Smrg#define IMAGE_MAX_HEIGHT_5597 288 9572b676d7Smrg 9672b676d7Smrg#if 0 9772b676d7Smrgstatic int oldH, oldW; 9872b676d7Smrg#endif 9972b676d7Smrg 10072b676d7Smrg/**************************************************************************** 10172b676d7Smrg * Raw register access : These routines directly interact with the sis's 10272b676d7Smrg * control aperature. Must not be called until after 10372b676d7Smrg * the board's pci memory has been mapped. 10472b676d7Smrg ****************************************************************************/ 10572b676d7Smrg 10672b676d7Smrg#if 0 10772b676d7Smrgstatic CARD32 _sisread(SISPtr pSiS, CARD32 reg) 10872b676d7Smrg{ 10972b676d7Smrg return *(pSiS->IOBase + reg); 11072b676d7Smrg} 11172b676d7Smrg 11272b676d7Smrgstatic void _siswrite(SISPtr pSiS, CARD32 reg, CARD32 data) 11372b676d7Smrg{ 11472b676d7Smrg *(pSiS->IOBase + reg) = data; 11572b676d7Smrg} 11672b676d7Smrg#endif 11772b676d7Smrg 11872b676d7Smrgstatic CARD8 getvideoreg(SISPtr pSiS, CARD8 reg) 11972b676d7Smrg{ 12072b676d7Smrg CARD8 ret; 12172b676d7Smrg inSISIDXREG(SISCR, reg, ret); 12272b676d7Smrg return ret; 12372b676d7Smrg} 12472b676d7Smrg 12572b676d7Smrgstatic __inline void setvideoreg(SISPtr pSiS, CARD8 reg, CARD8 data) 12672b676d7Smrg{ 12772b676d7Smrg outSISIDXREG(SISCR, reg, data); 12872b676d7Smrg} 12972b676d7Smrg 13072b676d7Smrgstatic __inline void setvideoregmask(SISPtr pSiS, CARD8 reg, CARD8 data, CARD8 mask) 13172b676d7Smrg{ 13272b676d7Smrg setSISIDXREGmask(SISCR, reg, data, mask); 13372b676d7Smrg} 13472b676d7Smrg 13572b676d7Smrg/* VBlank */ 13672b676d7Smrgstatic CARD8 vblank_active_CRT1(SISPtr pSiS) 13772b676d7Smrg{ 13872b676d7Smrg return (inSISREG(SISINPSTAT) & 0x08); 13972b676d7Smrg} 14072b676d7Smrg 14172b676d7Smrg/* Scanline - unused */ 14272b676d7Smrg#if 0 14372b676d7Smrgstatic CARD32 get_scanline_CRT1(SISPtr pSiS) 14472b676d7Smrg{ 14572b676d7Smrg CARD8 temp; 14672b676d7Smrg 14772b676d7Smrg temp = getvideoreg(pSiS, 0x20); 14872b676d7Smrg temp = getvideoreg(pSiS, 0x1b); 14972b676d7Smrg return((getvideoreg(pSiS, 0x1d) << 8) | getvideoreg(pSiS, 0x1c)); 15072b676d7Smrg} 15172b676d7Smrg#endif 15272b676d7Smrg 15372b676d7Smrgvoid SIS6326InitVideo(ScreenPtr pScreen) 15472b676d7Smrg{ 15574c14cd6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 15672b676d7Smrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 15772b676d7Smrg XF86VideoAdaptorPtr newAdaptor = NULL; 15872b676d7Smrg int num_adaptors; 15972b676d7Smrg 16072b676d7Smrg newAdaptor = SIS6326SetupImageVideo(pScreen); 16172b676d7Smrg if(newAdaptor) { 16272b676d7Smrg SIS6326InitOffscreenImages(pScreen); 16372b676d7Smrg } 16472b676d7Smrg 16572b676d7Smrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 16672b676d7Smrg 16772b676d7Smrg if(newAdaptor) { 16872b676d7Smrg if(!num_adaptors) { 16972b676d7Smrg num_adaptors = 1; 17072b676d7Smrg adaptors = &newAdaptor; 17172b676d7Smrg } else { 17272b676d7Smrg /* need to free this someplace */ 17374c14cd6Smrg newAdaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); 17472b676d7Smrg if(newAdaptors) { 17572b676d7Smrg memcpy(newAdaptors, adaptors, num_adaptors * 17672b676d7Smrg sizeof(XF86VideoAdaptorPtr)); 17772b676d7Smrg newAdaptors[num_adaptors] = newAdaptor; 17872b676d7Smrg adaptors = newAdaptors; 17972b676d7Smrg num_adaptors++; 18072b676d7Smrg } 18172b676d7Smrg } 18272b676d7Smrg } 18372b676d7Smrg 18472b676d7Smrg if(num_adaptors) 18572b676d7Smrg xf86XVScreenInit(pScreen, adaptors, num_adaptors); 18672b676d7Smrg 18772b676d7Smrg if(newAdaptors) 18874c14cd6Smrg free(newAdaptors); 18972b676d7Smrg} 19072b676d7Smrg 19172b676d7Smrg/* client libraries expect an encoding */ 19272b676d7Smrgstatic XF86VideoEncodingRec DummyEncoding = 19372b676d7Smrg{ 19472b676d7Smrg 0, 19572b676d7Smrg "XV_IMAGE", 19672b676d7Smrg IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, 19772b676d7Smrg {1, 1} 19872b676d7Smrg}; 19972b676d7Smrg 20072b676d7Smrgstatic XF86VideoEncodingRec DummyEncoding5597 = 20172b676d7Smrg{ 20272b676d7Smrg 0, 20372b676d7Smrg "XV_IMAGE", 20472b676d7Smrg IMAGE_MAX_WIDTH_5597, IMAGE_MAX_HEIGHT_5597, 20572b676d7Smrg {1, 1} 20672b676d7Smrg}; 20772b676d7Smrg 20872b676d7Smrg#define NUM_FORMATS 4 20972b676d7Smrg 21072b676d7Smrgstatic XF86VideoFormatRec SIS6326Formats[NUM_FORMATS] = 21172b676d7Smrg{ 21272b676d7Smrg { 8, PseudoColor}, 21372b676d7Smrg {15, TrueColor}, 21472b676d7Smrg {16, TrueColor}, 21572b676d7Smrg {24, TrueColor} 21672b676d7Smrg}; 21772b676d7Smrg 21872b676d7Smrg#define NUM_ATTRIBUTES 6 21972b676d7Smrg 22072b676d7Smrgstatic XF86AttributeRec SIS6326Attributes[NUM_ATTRIBUTES] = 22172b676d7Smrg{ 22272b676d7Smrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 22372b676d7Smrg {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 22472b676d7Smrg {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"}, 22572b676d7Smrg {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, 22672b676d7Smrg {XvSettable , 0, 0, "XV_SET_DEFAULTS"}, 22772b676d7Smrg {XvSettable | XvGettable, 0, 1, "XV_DISABLE_GRAPHICS"} 22872b676d7Smrg}; 22972b676d7Smrg 23072b676d7Smrg#define NUM_IMAGES 6 23172b676d7Smrg#define NUM_IMAGES_NOYV12 4 23272b676d7Smrg#define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */ 23372b676d7Smrg#define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */ 23472b676d7Smrg#define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */ 23572b676d7Smrg#define PIXEL_FMT_I420 FOURCC_I420 /* 0x30323449 */ 23672b676d7Smrg#define PIXEL_FMT_RGB5 0x35315652 23772b676d7Smrg#define PIXEL_FMT_RGB6 0x36315652 23872b676d7Smrg 23972b676d7Smrgstatic XF86ImageRec SIS6326Images[NUM_IMAGES] = 24072b676d7Smrg{ 24172b676d7Smrg XVIMAGE_YUY2, /* If order is changed, SIS6326OffscreenImages must be adapted */ 24272b676d7Smrg XVIMAGE_UYVY, 24372b676d7Smrg XVIMAGE_YV12, 24472b676d7Smrg XVIMAGE_I420, 24572b676d7Smrg { 24672b676d7Smrg 0x35315652, 24772b676d7Smrg XvRGB, 24872b676d7Smrg LSBFirst, 24972b676d7Smrg {'R','V','1','5', 25072b676d7Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 25172b676d7Smrg 16, 25272b676d7Smrg XvPacked, 25372b676d7Smrg 1, 25472b676d7Smrg 15, 0x7C00, 0x03E0, 0x001F, 25572b676d7Smrg 0, 0, 0, 25672b676d7Smrg 0, 0, 0, 25772b676d7Smrg 0, 0, 0, 25872b676d7Smrg {'R', 'V', 'B',0, 25972b676d7Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 26072b676d7Smrg XvTopToBottom 26172b676d7Smrg }, 26272b676d7Smrg { 26372b676d7Smrg 0x36315652, 26472b676d7Smrg XvRGB, 26572b676d7Smrg LSBFirst, 26672b676d7Smrg {'R','V','1','6', 26772b676d7Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 26872b676d7Smrg 16, 26972b676d7Smrg XvPacked, 27072b676d7Smrg 1, 27172b676d7Smrg 16, 0xF800, 0x07E0, 0x001F, 27272b676d7Smrg 0, 0, 0, 27372b676d7Smrg 0, 0, 0, 27472b676d7Smrg 0, 0, 0, 27572b676d7Smrg {'R', 'V', 'B',0, 27672b676d7Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 27772b676d7Smrg XvTopToBottom 27872b676d7Smrg } 27972b676d7Smrg}; 28072b676d7Smrg 28172b676d7Smrgstatic XF86ImageRec SIS6326ImagesNoYV12[NUM_IMAGES_NOYV12] = 28272b676d7Smrg{ 28372b676d7Smrg XVIMAGE_YUY2, /* If order is changed, SIS6326OffscreenImages must be adapted */ 28472b676d7Smrg XVIMAGE_UYVY, 28572b676d7Smrg { 28672b676d7Smrg 0x35315652, 28772b676d7Smrg XvRGB, 28872b676d7Smrg LSBFirst, 28972b676d7Smrg {'R','V','1','5', 29072b676d7Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 29172b676d7Smrg 16, 29272b676d7Smrg XvPacked, 29372b676d7Smrg 1, 29472b676d7Smrg 15, 0x7C00, 0x03E0, 0x001F, 29572b676d7Smrg 0, 0, 0, 29672b676d7Smrg 0, 0, 0, 29772b676d7Smrg 0, 0, 0, 29872b676d7Smrg {'R', 'V', 'B',0, 29972b676d7Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 30072b676d7Smrg XvTopToBottom 30172b676d7Smrg }, 30272b676d7Smrg { 30372b676d7Smrg 0x36315652, 30472b676d7Smrg XvRGB, 30572b676d7Smrg LSBFirst, 30672b676d7Smrg {'R','V','1','6', 30772b676d7Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 30872b676d7Smrg 16, 30972b676d7Smrg XvPacked, 31072b676d7Smrg 1, 31172b676d7Smrg 16, 0xF800, 0x07E0, 0x001F, 31272b676d7Smrg 0, 0, 0, 31372b676d7Smrg 0, 0, 0, 31472b676d7Smrg 0, 0, 0, 31572b676d7Smrg {'R', 'V', 'B',0, 31672b676d7Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 31772b676d7Smrg XvTopToBottom 31872b676d7Smrg } 31972b676d7Smrg}; 32072b676d7Smrg 32172b676d7Smrgtypedef struct { 32272b676d7Smrg int pixelFormat; 32372b676d7Smrg 32472b676d7Smrg CARD16 pitch; 32572b676d7Smrg 32672b676d7Smrg CARD8 keyOP; 32772b676d7Smrg 32872b676d7Smrg CARD8 HUSF; 32972b676d7Smrg CARD8 VUSF; 33072b676d7Smrg CARD8 HIntBit; 33172b676d7Smrg CARD8 wHPre; 33272b676d7Smrg CARD8 PitchMult; 33372b676d7Smrg 33472b676d7Smrg CARD16 srcW; 33572b676d7Smrg CARD16 srcH; 33672b676d7Smrg 33772b676d7Smrg BoxRec dstBox; 33872b676d7Smrg 33972b676d7Smrg CARD32 PSY; 34072b676d7Smrg CARD32 PSV; 34172b676d7Smrg CARD32 PSU; 34272b676d7Smrg CARD8 YUVEnd; 34372b676d7Smrg 34472b676d7Smrg CARD8 lineBufSize; 34572b676d7Smrg 34672b676d7Smrg CARD8 (*VBlankActiveFunc)(SISPtr); 34772b676d7Smrg/* CARD32 (*GetScanLineFunc)(SISPtr pSiS); */ 34872b676d7Smrg 34972b676d7Smrg} SISOverlayRec, *SISOverlayPtr; 35072b676d7Smrg 35172b676d7Smrgtypedef struct { 35272b676d7Smrg void * handle; 35372b676d7Smrg CARD32 bufAddr[2]; 35472b676d7Smrg 35572b676d7Smrg unsigned char currentBuf; 35672b676d7Smrg 35772b676d7Smrg short drw_x, drw_y, drw_w, drw_h; 35872b676d7Smrg short src_x, src_y, src_w, src_h; 35972b676d7Smrg int id; 36072b676d7Smrg short srcPitch, height, width; 36172b676d7Smrg CARD32 totalSize; 36272b676d7Smrg 36372b676d7Smrg char brightness; 36472b676d7Smrg unsigned char contrast; 36572b676d7Smrg 36672b676d7Smrg RegionRec clip; 36772b676d7Smrg CARD32 colorKey; 36872b676d7Smrg Bool autopaintColorKey; 36972b676d7Smrg 37072b676d7Smrg Bool disablegfx; 37172b676d7Smrg 37272b676d7Smrg CARD32 videoStatus; 37372b676d7Smrg Time offTime; 37472b676d7Smrg Time freeTime; 37572b676d7Smrg 37672b676d7Smrg short oldx1, oldx2, oldy1, oldy2; 37772b676d7Smrg int mustwait; 37872b676d7Smrg 37972b676d7Smrg Bool grabbedByV4L; /* V4L stuff */ 38072b676d7Smrg int pitch; 38172b676d7Smrg int offset; 38272b676d7Smrg 38372b676d7Smrg} SISPortPrivRec, *SISPortPrivPtr; 38472b676d7Smrg 38572b676d7Smrg#define GET_PORT_PRIVATE(pScrn) \ 38672b676d7Smrg (SISPortPrivPtr)((SISPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 38772b676d7Smrg 38872b676d7Smrgstatic void 38972b676d7SmrgSIS6326SetPortDefaults(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) 39072b676d7Smrg{ 39172b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 39272b676d7Smrg 39372b676d7Smrg pPriv->colorKey = 0x000101fe; 39472b676d7Smrg pPriv->videoStatus = 0; 39572b676d7Smrg pPriv->brightness = pSiS->XvDefBri; /* 0; - see sis_opt.c */ 39672b676d7Smrg pPriv->contrast = pSiS->XvDefCon; /* 4; */ 39772b676d7Smrg pPriv->autopaintColorKey = TRUE; 39872b676d7Smrg pPriv->disablegfx = pSiS->XvDefDisableGfx; 39972b676d7Smrg} 40072b676d7Smrg 40172b676d7Smrgstatic void 40272b676d7SmrgSIS6326ResetVideo(ScrnInfoPtr pScrn) 40372b676d7Smrg{ 40472b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 40572b676d7Smrg 40672b676d7Smrg /* Unlock registers */ 40772b676d7Smrg#ifdef UNLOCK_ALWAYS 40872b676d7Smrg sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); 40972b676d7Smrg#endif 41072b676d7Smrg if(getvideoreg(pSiS, Index_VI6326_Passwd) != 0xa1) { 41172b676d7Smrg setvideoreg(pSiS, Index_VI6326_Passwd, 0x86); 41272b676d7Smrg if(getvideoreg(pSiS, Index_VI6326_Passwd) != 0xa1) 41372b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 41472b676d7Smrg "Xv: Video password could not unlock video registers\n"); 41572b676d7Smrg } 41672b676d7Smrg 41772b676d7Smrg /* Initialize the overlay ----------------------------------- */ 41872b676d7Smrg 41972b676d7Smrg switch(pSiS->Chipset) { 42072b676d7Smrg case PCI_CHIP_SIS5597: 42172b676d7Smrg /* Disable overlay (D[1]) & capture (D[0]) */ 42272b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x03); 42372b676d7Smrg 42472b676d7Smrg /* What do these do? (Datasheet names these bits "reserved") */ 42572b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); 42672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); 42772b676d7Smrg 42872b676d7Smrg /* Select YUV format (D[6]) and "gfx + video" mode (D[4]), odd polarity? (D[7]) */ 42972b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0xD0); 43072b676d7Smrg /* No interrupt, no filter, disable dithering */ 43172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x7A); 43272b676d7Smrg /* Disable Brooktree support (D[6]) and system memory framebuffer (D[7]) */ 43372b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0xC0); 43472b676d7Smrg /* Disable video decimation (has a really strange effect if enabled) */ 43572b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc6, 0x00, 0x80); 43672b676d7Smrg break; 43772b676d7Smrg case PCI_CHIP_SIS6326: 43872b676d7Smrg /* Disable overlay (D[1]) & capture (D[0]) */ 43972b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x03); 44072b676d7Smrg 44172b676d7Smrg /* What do these do? (Datasheet names these bits "reserved") */ 44272b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); 44372b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); 44472b676d7Smrg 44572b676d7Smrg /* Select YUV format (D[6]) and "gfx + video" mode (D[4]), odd polarity? (D[7]) */ 44672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0xD0); 44772b676d7Smrg /* No interrupt, no filter, disable dithering */ 44872b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x7A); 44972b676d7Smrg /* Disable VMI (D[4:3]), Brooktree support (D[6]) and system memory framebuffer (D[7]) */ 45072b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0xF8); 45172b676d7Smrg /* Disable video decimation */ 45272b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc6, 0x00, 0x80); 45372b676d7Smrg break; 45472b676d7Smrg case PCI_CHIP_SIS530: 45572b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40); 45672b676d7Smrg /* Disable overlay (D[1]) */ 45772b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x02); 45872b676d7Smrg 45972b676d7Smrg /* What do D[3:2] do? (Datasheet names these bits "reserved") */ 46072b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); 46172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); 46272b676d7Smrg 46372b676d7Smrg /* Select YUV format (D[6]) and "gfx + video" mode (D[4]) */ 46472b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0x50); 46572b676d7Smrg break; 46672b676d7Smrg default: 46772b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 46872b676d7Smrg "Internal error: SiS6326ResetVideo() called with invalid chipset (%x)\n", 46972b676d7Smrg pSiS->Chipset); 47072b676d7Smrg return; 47172b676d7Smrg } 47272b676d7Smrg 47372b676d7Smrg /* Clear format selection */ 47472b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x04); 47572b676d7Smrg if(pSiS->oldChipset >= OC_SIS5597) { 47672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x00, 0x05); 47772b676d7Smrg } 47872b676d7Smrg 47972b676d7Smrg /* Select RGB Chromakey format (D[2]=0), CCIR 601 UV data format (D[1]=0) */ 48072b676d7Smrg /* D[1]: 1 = 2's complement, 0 = CCIR 601 format */ 48172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0x06); 48272b676d7Smrg 48372b676d7Smrg /* Reset contrast control */ 48472b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, 0x04, 0x1F); 48572b676d7Smrg 48672b676d7Smrg /* Set threshold */ 48772b676d7Smrg if(pSiS->oldChipset < OC_SIS6326) { 48872b676d7Smrg CARD8 temp; 48972b676d7Smrg inSISIDXREG(SISSR, 0x33, temp); /* Synchronous DRAM Timing? */ 49072b676d7Smrg if(temp & 0x01) temp = 0x50; 49172b676d7Smrg else temp = 0; 49272b676d7Smrg setvideoreg(pSiS, Index_VI6326_Play_Threshold_Low, temp); 49372b676d7Smrg setvideoreg(pSiS, Index_VI6326_Play_Threshold_High, temp); 49472b676d7Smrg } else { 49572b676d7Smrg CARD8 temp; 49672b676d7Smrg setvideoreg(pSiS, Index_VI6326_Play_Threshold_Low, 0x00); 49772b676d7Smrg setvideoreg(pSiS, Index_VI6326_Play_Threshold_High, 0x00); 49872b676d7Smrg inSISIDXREG(SISSR, 0x33, temp); /* Are we using SGRAM Timing? */ 49972b676d7Smrg if(temp & 0x01) temp = 0x10; 50072b676d7Smrg else temp = 0; 50172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc4, temp, 0x10); 50272b676d7Smrg } 50372b676d7Smrg 50472b676d7Smrg /* set default properties for overlay ------------------------------- */ 50572b676d7Smrg 50672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, 0x04, 0x07); 50772b676d7Smrg setvideoreg(pSiS, Index_VI6326_Brightness, 0x20); 50872b676d7Smrg 50972b676d7Smrg if(pSiS->oldChipset < OC_SIS6205A || pSiS->oldChipset > OC_SIS82204) { 51072b676d7Smrg setvideoregmask(pSiS, Index_VI6326_AlphaGraph, 0x00, 0xF8); 51172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_AlphaVideo, 0xF8, 0xF8); 51272b676d7Smrg } else { 51372b676d7Smrg setvideoregmask(pSiS, Index_VI6326_AlphaGraph, 0x00, 0xE1); 51472b676d7Smrg setvideoregmask(pSiS, Index_VI6326_AlphaVideo, 0xE1, 0xE1); 51572b676d7Smrg } 51672b676d7Smrg 51772b676d7Smrg} 51872b676d7Smrg 51972b676d7Smrgstatic XF86VideoAdaptorPtr 52072b676d7SmrgSIS6326SetupImageVideo(ScreenPtr pScreen) 52172b676d7Smrg{ 52274c14cd6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 52372b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 52472b676d7Smrg XF86VideoAdaptorPtr adapt; 52572b676d7Smrg SISPortPrivPtr pPriv; 52672b676d7Smrg 52772b676d7Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,1,99,1,0) 52872b676d7Smrg XAAInfoRecPtr pXAA = pSiS->AccelInfoPtr; 52972b676d7Smrg 53072b676d7Smrg if(!pXAA || !pXAA->FillSolidRects) 53172b676d7Smrg return NULL; 53272b676d7Smrg#endif 53372b676d7Smrg 53474c14cd6Smrg if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 53572b676d7Smrg sizeof(SISPortPrivRec) + 53672b676d7Smrg sizeof(DevUnion)))) 53772b676d7Smrg return NULL; 53872b676d7Smrg 53972b676d7Smrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 54072b676d7Smrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 54172b676d7Smrg adapt->name = "SIS 5597/5598/6326/530/620 Video Overlay"; 54272b676d7Smrg adapt->nEncodings = 1; 54372b676d7Smrg if(pSiS->oldChipset < OC_SIS6326) { 54472b676d7Smrg adapt->pEncodings = &DummyEncoding5597; 54572b676d7Smrg } else { 54672b676d7Smrg adapt->pEncodings = &DummyEncoding; 54772b676d7Smrg } 54872b676d7Smrg adapt->nFormats = NUM_FORMATS; 54972b676d7Smrg adapt->pFormats = SIS6326Formats; 55072b676d7Smrg adapt->nPorts = 1; 55172b676d7Smrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 55272b676d7Smrg 55372b676d7Smrg pPriv = (SISPortPrivPtr)(&adapt->pPortPrivates[1]); 55472b676d7Smrg 55572b676d7Smrg adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 55672b676d7Smrg adapt->pAttributes = SIS6326Attributes; 55772b676d7Smrg adapt->nAttributes = NUM_ATTRIBUTES; 55872b676d7Smrg if(pSiS->NoYV12 == 1) { 55972b676d7Smrg adapt->nImages = NUM_IMAGES_NOYV12; 56072b676d7Smrg adapt->pImages = SIS6326ImagesNoYV12; 56172b676d7Smrg } else { 56272b676d7Smrg adapt->nImages = NUM_IMAGES; 56372b676d7Smrg adapt->pImages = SIS6326Images; 56472b676d7Smrg } 56572b676d7Smrg adapt->PutVideo = NULL; 56672b676d7Smrg adapt->PutStill = NULL; 56772b676d7Smrg adapt->GetVideo = NULL; 56872b676d7Smrg adapt->GetStill = NULL; 56972b676d7Smrg adapt->StopVideo = SIS6326StopVideo; 57072b676d7Smrg adapt->SetPortAttribute = SIS6326SetPortAttribute; 57172b676d7Smrg adapt->GetPortAttribute = SIS6326GetPortAttribute; 57272b676d7Smrg adapt->QueryBestSize = SIS6326QueryBestSize; 57372b676d7Smrg adapt->PutImage = SIS6326PutImage; 57472b676d7Smrg adapt->QueryImageAttributes = SIS6326QueryImageAttributes; 57572b676d7Smrg 57672b676d7Smrg pPriv->videoStatus = 0; 57772b676d7Smrg pPriv->currentBuf = 0; 57872b676d7Smrg pPriv->handle = NULL; 57972b676d7Smrg pPriv->grabbedByV4L= FALSE; 58072b676d7Smrg 58172b676d7Smrg SIS6326SetPortDefaults(pScrn, pPriv); 58272b676d7Smrg 58372b676d7Smrg /* gotta uninit this someplace */ 58472b676d7Smrg#if defined(REGION_NULL) 58572b676d7Smrg REGION_NULL(pScreen, &pPriv->clip); 58672b676d7Smrg#else 58772b676d7Smrg REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); 58872b676d7Smrg#endif 58972b676d7Smrg 59072b676d7Smrg pSiS->adaptor = adapt; 59172b676d7Smrg 59272b676d7Smrg xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 59372b676d7Smrg xvContrast = MAKE_ATOM("XV_CONTRAST"); 59472b676d7Smrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 59572b676d7Smrg xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); 59672b676d7Smrg xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); 59772b676d7Smrg xvDisableGfx = MAKE_ATOM("XV_DISABLE_GRAPHICS"); 59872b676d7Smrg 59972b676d7Smrg SIS6326ResetVideo(pScrn); 60072b676d7Smrg pSiS->ResetXv = SIS6326ResetVideo; 60172b676d7Smrg 60272b676d7Smrg return adapt; 60372b676d7Smrg} 60472b676d7Smrg 60572b676d7Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,3,0) 60672b676d7Smrgstatic Bool 60772b676d7SmrgRegionsEqual(RegionPtr A, RegionPtr B) 60872b676d7Smrg{ 60972b676d7Smrg int *dataA, *dataB; 61072b676d7Smrg int num; 61172b676d7Smrg 61272b676d7Smrg num = REGION_NUM_RECTS(A); 61372b676d7Smrg if(num != REGION_NUM_RECTS(B)) 61472b676d7Smrg return FALSE; 61572b676d7Smrg 61672b676d7Smrg if((A->extents.x1 != B->extents.x1) || 61772b676d7Smrg (A->extents.x2 != B->extents.x2) || 61872b676d7Smrg (A->extents.y1 != B->extents.y1) || 61972b676d7Smrg (A->extents.y2 != B->extents.y2)) 62072b676d7Smrg return FALSE; 62172b676d7Smrg 62272b676d7Smrg dataA = (int*)REGION_RECTS(A); 62372b676d7Smrg dataB = (int*)REGION_RECTS(B); 62472b676d7Smrg 62572b676d7Smrg while(num--) { 62672b676d7Smrg if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) 62772b676d7Smrg return FALSE; 62872b676d7Smrg dataA += 2; 62972b676d7Smrg dataB += 2; 63072b676d7Smrg } 63172b676d7Smrg 63272b676d7Smrg return TRUE; 63372b676d7Smrg} 63472b676d7Smrg#endif 63572b676d7Smrg 63672b676d7Smrgstatic int 63772b676d7SmrgSIS6326SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, 63872b676d7Smrg INT32 value, pointer data) 63972b676d7Smrg{ 64072b676d7Smrg SISPortPrivPtr pPriv = (SISPortPrivPtr)data; 64172b676d7Smrg 64272b676d7Smrg if(attribute == xvBrightness) { 64372b676d7Smrg if((value < -128) || (value > 127)) 64472b676d7Smrg return BadValue; 64572b676d7Smrg pPriv->brightness = value; 64672b676d7Smrg } else if(attribute == xvContrast) { 64772b676d7Smrg if((value < 0) || (value > 7)) 64872b676d7Smrg return BadValue; 64972b676d7Smrg pPriv->contrast = value; 65072b676d7Smrg } else if(attribute == xvColorKey) { 65172b676d7Smrg pPriv->colorKey = value; 65272b676d7Smrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 65372b676d7Smrg } else if (attribute == xvAutopaintColorKey) { 65472b676d7Smrg if((value < 0) || (value > 1)) 65572b676d7Smrg return BadValue; 65672b676d7Smrg pPriv->autopaintColorKey = value; 65772b676d7Smrg } else if(attribute == xvDisableGfx) { 65872b676d7Smrg if((value < 0) || (value > 1)) 65972b676d7Smrg return BadValue; 66072b676d7Smrg pPriv->disablegfx = value; 66172b676d7Smrg } else if (attribute == xvSetDefaults) { 66272b676d7Smrg SIS6326SetPortDefaults(pScrn, pPriv); 66372b676d7Smrg } else return BadMatch; 66472b676d7Smrg return Success; 66572b676d7Smrg} 66672b676d7Smrg 66772b676d7Smrgstatic int 66872b676d7SmrgSIS6326GetPortAttribute( 66972b676d7Smrg ScrnInfoPtr pScrn, 67072b676d7Smrg Atom attribute, 67172b676d7Smrg INT32 *value, 67272b676d7Smrg pointer data 67372b676d7Smrg){ 67472b676d7Smrg SISPortPrivPtr pPriv = (SISPortPrivPtr)data; 67572b676d7Smrg 67672b676d7Smrg if(attribute == xvBrightness) { 67772b676d7Smrg *value = pPriv->brightness; 67872b676d7Smrg } else if(attribute == xvContrast) { 67972b676d7Smrg *value = pPriv->contrast; 68072b676d7Smrg } else if(attribute == xvColorKey) { 68172b676d7Smrg *value = pPriv->colorKey; 68272b676d7Smrg } else if (attribute == xvAutopaintColorKey) { 68372b676d7Smrg *value = (pPriv->autopaintColorKey) ? 1 : 0; 68472b676d7Smrg } else if (attribute == xvDisableGfx) { 68572b676d7Smrg *value = (pPriv->disablegfx) ? 1 : 0; 68672b676d7Smrg } else return BadMatch; 68772b676d7Smrg return Success; 68872b676d7Smrg} 68972b676d7Smrg 69072b676d7Smrgstatic void 69172b676d7SmrgSIS6326QueryBestSize( 69272b676d7Smrg ScrnInfoPtr pScrn, 69372b676d7Smrg Bool motion, 69472b676d7Smrg short vid_w, short vid_h, 69572b676d7Smrg short drw_w, short drw_h, 69672b676d7Smrg unsigned int *p_w, unsigned int *p_h, 69772b676d7Smrg pointer data 69872b676d7Smrg){ 69972b676d7Smrg *p_w = drw_w; 70072b676d7Smrg *p_h = drw_h; 70172b676d7Smrg 70272b676d7Smrg /* TODO: report the HW limitation */ 70372b676d7Smrg} 70472b676d7Smrg 70572b676d7Smrgstatic void /* V 530/6326 */ 70672b676d7Smrgcalc_scale_factor(SISPtr pSiS, SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, 70772b676d7Smrg SISPortPrivPtr pPriv) 70872b676d7Smrg{ 70972b676d7Smrg CARD32 temp=0; 71072b676d7Smrg 71172b676d7Smrg int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1; 71272b676d7Smrg int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1; 71372b676d7Smrg int srcW = pOverlay->srcW; 71472b676d7Smrg int srcH = pOverlay->srcH; 71572b676d7Smrg 71672b676d7Smrg /* For double scan modes, we need to double the height */ 71772b676d7Smrg if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { 71872b676d7Smrg dstH <<= 1; 71972b676d7Smrg } 72072b676d7Smrg /* For interlace modes, we need to half the height */ 72172b676d7Smrg if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) { 72272b676d7Smrg dstH >>= 1; 72372b676d7Smrg } 72472b676d7Smrg 72572b676d7Smrg /* Horizontal */ 72672b676d7Smrg if(dstW < IMAGE_MIN_WIDTH) dstW = IMAGE_MIN_WIDTH; 72772b676d7Smrg if(dstW == srcW) { 72872b676d7Smrg pOverlay->HUSF = 0x00; 72972b676d7Smrg pOverlay->HIntBit = 0x01; 73072b676d7Smrg } else if(dstW > srcW) { 73172b676d7Smrg pOverlay->HIntBit = 0x00; 73272b676d7Smrg temp = srcW * 64 / (dstW + 1); 73372b676d7Smrg if(temp > 63) temp = 63; 73472b676d7Smrg pOverlay->HUSF = temp; 73572b676d7Smrg } else { 73672b676d7Smrg /* 6326 can't scale below factor .440 - to check with 530/620 */ 73772b676d7Smrg if(((dstW * 1000) / srcW) < 440) dstW = ((srcW * 440) / 1000) + 1; 73872b676d7Smrg temp = srcW / dstW; 73972b676d7Smrg if(temp > 15) temp = 15; 74072b676d7Smrg pOverlay->HIntBit = temp; 74172b676d7Smrg temp = srcW * 64 / dstW; 74272b676d7Smrg pOverlay->HUSF = temp - (pOverlay->HIntBit * 64); 74372b676d7Smrg } 74472b676d7Smrg 74572b676d7Smrg /* Vertical */ 74672b676d7Smrg if(dstH < IMAGE_MIN_HEIGHT) dstH = IMAGE_MIN_HEIGHT; 74772b676d7Smrg if(dstH == srcH) { 74872b676d7Smrg pOverlay->VUSF = 0x00; 74972b676d7Smrg pOverlay->PitchMult = 1; 75072b676d7Smrg } else if(dstH > srcH) { 75172b676d7Smrg temp = srcH * 64 / (dstH + 1); 75272b676d7Smrg if (temp > 63) temp = 63; 75372b676d7Smrg pOverlay->VUSF = temp; 75472b676d7Smrg pOverlay->PitchMult = 1; 75572b676d7Smrg } else { 75672b676d7Smrg /* 6326 can't scale below factor .440 - to check with 530/620 */ 75772b676d7Smrg if(((dstH * 1000) / srcH) < 440) dstH = ((srcH * 440) / 1000) + 1; 75872b676d7Smrg temp = srcH / dstH; 75972b676d7Smrg if(srcH % dstH) { 76072b676d7Smrg temp++; 76172b676d7Smrg pOverlay->VUSF = (srcH * 64) / (temp * dstH); 76272b676d7Smrg } else { 76372b676d7Smrg pOverlay->VUSF = 0x00; 76472b676d7Smrg } 76572b676d7Smrg pOverlay->PitchMult = temp; 76672b676d7Smrg } 76772b676d7Smrg} 76872b676d7Smrg 76972b676d7Smrgstatic void 77072b676d7Smrgcalc_line_buf_size(SISOverlayPtr pOverlay) 77172b676d7Smrg{ 77272b676d7Smrg CARD32 I; 77372b676d7Smrg CARD32 line = pOverlay->srcW; 77472b676d7Smrg 77572b676d7Smrg if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) || 77672b676d7Smrg (pOverlay->pixelFormat == PIXEL_FMT_I420) ) { 77772b676d7Smrg I = (line >> 5) + (((line >> 6) * 2)) + 3; 77872b676d7Smrg I <<= 5; 77972b676d7Smrg } else { /* YUV2, UYVY, RGB */ 78072b676d7Smrg I = line << 1; 78172b676d7Smrg if(I & 7) I += 8; 78272b676d7Smrg } 78372b676d7Smrg I += 8; 78472b676d7Smrg I >>= 3; 78572b676d7Smrg pOverlay->lineBufSize = (CARD8)I; 78672b676d7Smrg} 78772b676d7Smrg 78872b676d7Smrgstatic void 78972b676d7Smrgmerge_line_buf(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable) 79072b676d7Smrg{ 79172b676d7Smrg if(enable) { 79272b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc5, 0x10, 0x10); 79372b676d7Smrg } else { 79472b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc5, 0x00, 0x10); 79572b676d7Smrg } 79672b676d7Smrg} 79772b676d7Smrg 79872b676d7Smrgstatic void 79972b676d7Smrgset_format(SISPtr pSiS, SISOverlayPtr pOverlay) 80072b676d7Smrg{ 80172b676d7Smrg CARD8 fmt, misc0, misc1, misc4; 80272b676d7Smrg 80372b676d7Smrg switch(pOverlay->pixelFormat) { 80472b676d7Smrg case PIXEL_FMT_YV12: 80572b676d7Smrg case PIXEL_FMT_I420: /* V/530 V/6326 */ 80672b676d7Smrg fmt = 0x80; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ 80772b676d7Smrg misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */ 80872b676d7Smrg misc4 = 0x05; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */ 80972b676d7Smrg misc1 = 0xff; 81072b676d7Smrg break; 81172b676d7Smrg case PIXEL_FMT_UYVY: 81272b676d7Smrg fmt = 0x00; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ 81372b676d7Smrg misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */ 81472b676d7Smrg misc4 = 0x00; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */ 81572b676d7Smrg misc1 = 0xff; 81672b676d7Smrg break; 81772b676d7Smrg case PIXEL_FMT_YUY2: /* V/530 V/6326 */ 81872b676d7Smrg fmt = 0x80; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ 81972b676d7Smrg misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */ 82072b676d7Smrg misc4 = 0x00; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */ 82172b676d7Smrg misc1 = 0xff; 82272b676d7Smrg break; 82372b676d7Smrg case PIXEL_FMT_RGB6: /* V/530 V/6326 */ 82472b676d7Smrg fmt = 0x40; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ 82572b676d7Smrg misc0 = 0x00; /* D[6]: 1 = YUV, 0 = RGB */ 82672b676d7Smrg misc4 = 0xff; 82772b676d7Smrg misc1 = 0x00; /* D[2] = Capture format selection (DS5597) - WDR sets this */ 82872b676d7Smrg break; 82972b676d7Smrg case PIXEL_FMT_RGB5: /* V/530 V/6326 */ 83072b676d7Smrg default: 83172b676d7Smrg fmt = 0x00; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ 83272b676d7Smrg misc0 = 0x00; /* D[6]: 1 = YUV, 0 = RGB */ 83372b676d7Smrg misc4 = 0xff; 83472b676d7Smrg misc1 = 0x04; /* D[2] = Capture format selection (DS5597) - WDR sets this */ 83572b676d7Smrg break; 83672b676d7Smrg } 83772b676d7Smrg 83872b676d7Smrg setvideoregmask(pSiS, Index_VI6326_VideoFormatSelect, fmt, 0xC0); 83972b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, misc0, 0x40); 84072b676d7Smrg if(misc4 == 0xff) { 84172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc1, misc1, 0x04); 84272b676d7Smrg if(pSiS->oldChipset >= OC_SIS5597) { 84372b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x00, 0x05); 84472b676d7Smrg } 84572b676d7Smrg } else { 84672b676d7Smrg if(pSiS->oldChipset >= OC_SIS5597) { 84772b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc4, misc4, 0x05); 84872b676d7Smrg } 84972b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x04); 85072b676d7Smrg } 85172b676d7Smrg} 85272b676d7Smrg 85372b676d7Smrgstatic void 85472b676d7Smrgset_colorkey(SISPtr pSiS, CARD32 colorkey) 85572b676d7Smrg{ 85672b676d7Smrg CARD8 r, g, b, s; 85772b676d7Smrg 85872b676d7Smrg b = (CARD8)(colorkey & 0xFF); 85972b676d7Smrg g = (CARD8)((colorkey >> 8) & 0xFF); 86072b676d7Smrg r = (CARD8)((colorkey >> 16) & 0xFF); 86172b676d7Smrg 86272b676d7Smrg if(pSiS->CurrentLayout.bitsPerPixel >= 24) { 86372b676d7Smrg s = b; 86472b676d7Smrg b = r; 86572b676d7Smrg r = s; 86672b676d7Smrg } 86772b676d7Smrg 86872b676d7Smrg setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Blue_Min ,(CARD8)b); 86972b676d7Smrg setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Green_Min ,(CARD8)g); 87072b676d7Smrg setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Red_Min ,(CARD8)r); 87172b676d7Smrg 87272b676d7Smrg setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Blue_Max ,(CARD8)b); 87372b676d7Smrg setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Green_Max ,(CARD8)g); 87472b676d7Smrg setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Red_Max ,(CARD8)r); 87572b676d7Smrg} 87672b676d7Smrg 87772b676d7Smrgstatic __inline void 87872b676d7Smrgset_brightness(SISPtr pSiS, CARD8 brightness) 87972b676d7Smrg{ 88072b676d7Smrg setvideoreg(pSiS, Index_VI6326_Brightness, brightness); 88172b676d7Smrg} 88272b676d7Smrg 88372b676d7Smrgstatic __inline void 88472b676d7Smrgset_contrast(SISPtr pSiS, CARD8 contrast) 88572b676d7Smrg{ 88672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, contrast, 0x07); 88772b676d7Smrg} 88872b676d7Smrg 88972b676d7Smrgstatic void 89072b676d7Smrgset_contrast_data(SISPtr pSiS, int value) 89172b676d7Smrg{ 89272b676d7Smrg unsigned long temp; 89372b676d7Smrg 89472b676d7Smrg if(value < 10000) temp = 0; 89572b676d7Smrg else temp = (value - 10000) / 20000; 89672b676d7Smrg if(temp > 3) temp = 3; 89772b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, (temp << 6), 0xC0); 89872b676d7Smrg switch(temp) { 89972b676d7Smrg case 0: temp = 2048; break; 90072b676d7Smrg case 1: temp = 4096; break; 90172b676d7Smrg case 2: temp = 8192; break; 90272b676d7Smrg case 3: temp = 16384; break; 90372b676d7Smrg } 90472b676d7Smrg temp <<= 10; 90572b676d7Smrg temp /= value; 90672b676d7Smrg setvideoreg(pSiS, Index_VI6326_Contrast_Factor, temp); 90772b676d7Smrg} 90872b676d7Smrg 90972b676d7Smrgstatic __inline void 91072b676d7Smrgset_disablegfx(SISPtr pSiS, Bool mybool) 91172b676d7Smrg{ 91272b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, mybool ? 0x10 : 0x00, 0x10); 91372b676d7Smrg} 91472b676d7Smrg 91572b676d7Smrgstatic void 91672b676d7Smrgset_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index) 91772b676d7Smrg{ 91872b676d7Smrg ScrnInfoPtr pScrn = pSiS->pScrn; 91972b676d7Smrg 92072b676d7Smrg CARD16 pitch=0; 92172b676d7Smrg CARD8 h_over=0, v_over=0; 92272b676d7Smrg CARD16 top, bottom, left, right; 92372b676d7Smrg CARD16 screenX = pSiS->CurrentLayout.mode->HDisplay; 92472b676d7Smrg CARD16 screenY = pSiS->CurrentLayout.mode->VDisplay; 92572b676d7Smrg CARD32 watchdog; 92672b676d7Smrg 92772b676d7Smrg top = pOverlay->dstBox.y1; 92872b676d7Smrg bottom = pOverlay->dstBox.y2; 92972b676d7Smrg if(bottom > screenY) { 93072b676d7Smrg bottom = screenY; 93172b676d7Smrg } 93272b676d7Smrg 93372b676d7Smrg left = pOverlay->dstBox.x1; 93472b676d7Smrg right = pOverlay->dstBox.x2; 93572b676d7Smrg if(right > screenX) { 93672b676d7Smrg right = screenX; 93772b676d7Smrg } 93872b676d7Smrg 93972b676d7Smrg /* TW: DoubleScan modes require Y coordinates * 2 */ 94072b676d7Smrg if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { 94172b676d7Smrg top <<= 1; 94272b676d7Smrg bottom <<= 1; 94372b676d7Smrg } 94472b676d7Smrg /* TW: Interlace modes require Y coordinates / 2 */ 94572b676d7Smrg if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) { 94672b676d7Smrg top >>= 1; 94772b676d7Smrg bottom >>= 1; 94872b676d7Smrg } 94972b676d7Smrg 95072b676d7Smrg h_over = (((left>>8) & 0x07) | ((right>>4) & 0x70)); 95172b676d7Smrg v_over = (((top>>8) & 0x07) | ((bottom>>4) & 0x70)); 95272b676d7Smrg 95372b676d7Smrg pitch = pOverlay->pitch * pOverlay->PitchMult; 95472b676d7Smrg pitch >>= 2; /* Datasheet: Unit = double word - verified */ 95572b676d7Smrg if(pitch > 0xfff) { 95672b676d7Smrg pitch = pOverlay->pitch * (0xFFF * 2 / pOverlay->pitch); 95772b676d7Smrg pOverlay->VUSF = 0x3F; 95872b676d7Smrg } 95972b676d7Smrg 96072b676d7Smrg /* set color key */ 96172b676d7Smrg set_colorkey(pSiS, pPriv->colorKey); 96272b676d7Smrg 96372b676d7Smrg /* set color key mode */ 96472b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Key_Overlay_OP, pOverlay->keyOP, 0x0f); 96572b676d7Smrg 96672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); 96772b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); 96872b676d7Smrg 96972b676d7Smrg /* Set Y buf pitch */ /* Datasheet: Unit = double word - verified */ 97072b676d7Smrg setvideoreg(pSiS, Index_VI6326_Disp_Y_Buf_Pitch_Low, (CARD8)(pitch)); 97172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Disp_Y_Buf_Pitch_High, (CARD8)(pitch>>8), 0x0f); 97272b676d7Smrg /* Set U/V pitch if using planar formats */ 97372b676d7Smrg if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) || 97472b676d7Smrg (pOverlay->pixelFormat == PIXEL_FMT_I420) ) { 97572b676d7Smrg /* Set U/V pitch */ /* Datasheet: Unit = double word - verified */ 97672b676d7Smrg setvideoreg(pSiS, Index_VI6326_Disp_UV_Buf_Pitch_Low, (CARD8)pitch >> 1); 97772b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Disp_UV_Buf_Pitch_High, (CARD8)(pitch >> 9), 0x0f); 97872b676d7Smrg } 97972b676d7Smrg 98072b676d7Smrg /* set line buffer size */ 98172b676d7Smrg setvideoreg(pSiS, Index_VI6326_Line_Buffer_Size, pOverlay->lineBufSize); 98272b676d7Smrg 98372b676d7Smrg /* set scale factor */ 98472b676d7Smrg setvideoreg(pSiS, Index_VI6326_Hor_Scale, (CARD8)((pOverlay->HUSF) | 0xC0)); 98572b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Hor_Scale_Integer, (CARD8)(pOverlay->HIntBit), 0x0F); 98672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Ver_Scale, (CARD8)(pOverlay->VUSF), 0x3F); 98772b676d7Smrg 98872b676d7Smrg /* TW: We don't have to wait for vertical retrace in all cases */ 98972b676d7Smrg if(pPriv->mustwait) { 99072b676d7Smrg watchdog = WATCHDOG_DELAY; 99172b676d7Smrg while ((!pOverlay->VBlankActiveFunc(pSiS)) && --watchdog); 99272b676d7Smrg if(!watchdog) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 99372b676d7Smrg "Xv: Waiting for vertical retrace timed-out\n"); 99472b676d7Smrg } 99572b676d7Smrg 99672b676d7Smrg /* set destination window position */ 99772b676d7Smrg setvideoreg(pSiS, Index_VI6326_Win_Hor_Disp_Start_Low, (CARD8)left); 99872b676d7Smrg setvideoreg(pSiS, Index_VI6326_Win_Hor_Disp_End_Low, (CARD8)right); 99972b676d7Smrg setvideoreg(pSiS, Index_VI6326_Win_Hor_Over, (CARD8)h_over); 100072b676d7Smrg 100172b676d7Smrg setvideoreg(pSiS, Index_VI6326_Win_Ver_Disp_Start_Low, (CARD8)top); 100272b676d7Smrg setvideoreg(pSiS, Index_VI6326_Win_Ver_Disp_End_Low, (CARD8)bottom); 100372b676d7Smrg setvideoreg(pSiS, Index_VI6326_Win_Ver_Over, (CARD8)v_over); 100472b676d7Smrg 100572b676d7Smrg /* Set Y start address */ 100672b676d7Smrg setvideoreg(pSiS, Index_VI6326_Disp_Y_Buf_Start_Low, (CARD8)(pOverlay->PSY)); 100772b676d7Smrg setvideoreg(pSiS, Index_VI6326_Disp_Y_Buf_Start_Middle, (CARD8)((pOverlay->PSY)>>8)); 100872b676d7Smrg if(pSiS->oldChipset <= OC_SIS6326) { /* all old chipsets incl 6326 */ 100972b676d7Smrg /* Set overflow bits */ 101072b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Disp_Capt_Y_Buf_Start_High, 101172b676d7Smrg (CARD8)(((pOverlay->PSY)>>12) & 0xF0), 0xF0); 101272b676d7Smrg /* Set framebuffer end address */ 101372b676d7Smrg setvideoreg(pSiS, Index_VI6326_Disp_Y_End, (CARD8)(pOverlay->YUVEnd)); 101472b676d7Smrg } else { /* 530/620 */ 101572b676d7Smrg /* Set overflow bits */ 101672b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Disp_Capt_Y_Buf_Start_High, 101772b676d7Smrg (CARD8)(((pOverlay->PSY)>>13) & 0xF8), 0xF8); 101872b676d7Smrg } 101972b676d7Smrg 102072b676d7Smrg /* Set U/V start addresses if using plane formats */ 102172b676d7Smrg if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) || 102272b676d7Smrg (pOverlay->pixelFormat == PIXEL_FMT_I420) ) { 102372b676d7Smrg 102472b676d7Smrg CARD32 PSU = pOverlay->PSU; 102572b676d7Smrg CARD32 PSV = pOverlay->PSV; 102672b676d7Smrg 102772b676d7Smrg /* set U/V start address */ 102872b676d7Smrg setvideoreg(pSiS, Index_VI6326_U_Buf_Start_Low, (CARD8)PSU); 102972b676d7Smrg setvideoreg(pSiS, Index_VI6326_U_Buf_Start_Middle,(CARD8)(PSU >> 8)); 103072b676d7Smrg 103172b676d7Smrg setvideoreg(pSiS, Index_VI6326_V_Buf_Start_Low, (CARD8)PSV); 103272b676d7Smrg setvideoreg(pSiS, Index_VI6326_V_Buf_Start_Middle,(CARD8)(PSV >> 8)); 103372b676d7Smrg 103472b676d7Smrg setvideoreg(pSiS, Index_VI6326_UV_Buf_Start_High, 103572b676d7Smrg (CARD8)(((PSU >> 16) & 0x0F) | ((PSV >> 12) & 0xF0)) ); 103672b676d7Smrg 103772b676d7Smrg if(pSiS->oldChipset > OC_SIS6326) { 103872b676d7Smrg /* Set bit 20 of the addresses in Misc5 (530/620 only) */ 103972b676d7Smrg setvideoreg(pSiS, Index_VI6326_Control_Misc5, 104072b676d7Smrg (CARD8)(((PSU >> (20-1)) & 0x02) | ((PSV >> (20-2)) & 0x04)) ); 104172b676d7Smrg } 104272b676d7Smrg } 104372b676d7Smrg 104472b676d7Smrg /* set brightness and contrast */ 104572b676d7Smrg set_brightness(pSiS, pPriv->brightness); 104672b676d7Smrg if(pSiS->oldChipset > OC_SIS6205C) { 104772b676d7Smrg set_contrast_data(pSiS, (pOverlay->dstBox.x2 - pOverlay->dstBox.x1) * 104872b676d7Smrg (pOverlay->dstBox.y2 - pOverlay->dstBox.y1)); 104972b676d7Smrg set_contrast(pSiS, pPriv->contrast); 105072b676d7Smrg } 105172b676d7Smrg 105272b676d7Smrg /* enable/disable graphics display around overlay */ 105372b676d7Smrg set_disablegfx(pSiS, pPriv->disablegfx); 105472b676d7Smrg 105572b676d7Smrg /* set format */ 105672b676d7Smrg set_format(pSiS, pOverlay); 105772b676d7Smrg} 105872b676d7Smrg 105972b676d7Smrg/* Overlay MUST NOT be switched off while beam is over it */ 106072b676d7Smrgstatic void 106172b676d7Smrgclose_overlay(SISPtr pSiS, SISPortPrivPtr pPriv) 106272b676d7Smrg{ 106372b676d7Smrg CARD32 watchdog; 106472b676d7Smrg 106572b676d7Smrg watchdog = WATCHDOG_DELAY; 106672b676d7Smrg while((!vblank_active_CRT1(pSiS)) && --watchdog); 106772b676d7Smrg if(pSiS->oldChipset > OC_SIS6326) { 106872b676d7Smrg /* what is this? */ 106972b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40); 107072b676d7Smrg } 107172b676d7Smrg /* disable overlay */ 107272b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x02); 107372b676d7Smrg} 107472b676d7Smrg 107572b676d7Smrgstatic void 107672b676d7SmrgSIS6326DisplayVideo(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) 107772b676d7Smrg{ 107872b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 107972b676d7Smrg 108072b676d7Smrg short srcPitch = pPriv->srcPitch; 108172b676d7Smrg short height = pPriv->height; 108272b676d7Smrg short width = pPriv->width; 108372b676d7Smrg SISOverlayRec overlay; 108472b676d7Smrg int srcOffsetX=0, srcOffsetY=0; 108572b676d7Smrg int sx, sy; 108672b676d7Smrg int index = 0; 108772b676d7Smrg int pitch; 108872b676d7Smrg 108972b676d7Smrg memset(&overlay, 0, sizeof(overlay)); 109072b676d7Smrg overlay.pixelFormat = pPriv->id; 109172b676d7Smrg overlay.pitch = srcPitch; 109272b676d7Smrg overlay.keyOP = VI6326_ROP_DestKey; /* DestKey mode */ 109372b676d7Smrg 109472b676d7Smrg overlay.dstBox.x1 = pPriv->drw_x - pScrn->frameX0; 109572b676d7Smrg overlay.dstBox.x2 = pPriv->drw_x + pPriv->drw_w - pScrn->frameX0; 109672b676d7Smrg overlay.dstBox.y1 = pPriv->drw_y - pScrn->frameY0; 109772b676d7Smrg overlay.dstBox.y2 = pPriv->drw_y + pPriv->drw_h - pScrn->frameY0; 109872b676d7Smrg 109972b676d7Smrg if((overlay.dstBox.x1 > overlay.dstBox.x2) || 110072b676d7Smrg (overlay.dstBox.y1 > overlay.dstBox.y2)) 110172b676d7Smrg return; 110272b676d7Smrg 110372b676d7Smrg if((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0)) 110472b676d7Smrg return; 110572b676d7Smrg 110672b676d7Smrg if(overlay.dstBox.x1 < 0) { 110772b676d7Smrg srcOffsetX = pPriv->src_w * (-overlay.dstBox.x1) / pPriv->drw_w; 110872b676d7Smrg overlay.dstBox.x1 = 0; 110972b676d7Smrg } 111072b676d7Smrg if(overlay.dstBox.y1 < 0) { 111172b676d7Smrg srcOffsetY = pPriv->src_h * (-overlay.dstBox.y1) / pPriv->drw_h; 111272b676d7Smrg overlay.dstBox.y1 = 0; 111372b676d7Smrg } 111472b676d7Smrg 111572b676d7Smrg switch(pPriv->id){ 111672b676d7Smrg case PIXEL_FMT_YV12: 111772b676d7Smrg sx = (pPriv->src_x + srcOffsetX) & ~7; 111872b676d7Smrg sy = (pPriv->src_y + srcOffsetY) & ~1; 111972b676d7Smrg pitch = (width + 3) & ~3; 112072b676d7Smrg overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy * pitch; 112172b676d7Smrg overlay.PSV = overlay.PSY + pitch * height; 112272b676d7Smrg overlay.PSU = overlay.PSV + ((((width >> 1) + 3) & ~3) * (height >> 1)); 112372b676d7Smrg overlay.PSY >>= 2; 112472b676d7Smrg overlay.PSV >>= 2; 112572b676d7Smrg overlay.PSU >>= 2; 112672b676d7Smrg break; 112772b676d7Smrg case PIXEL_FMT_I420: 112872b676d7Smrg sx = (pPriv->src_x + srcOffsetX) & ~7; 112972b676d7Smrg sy = (pPriv->src_y + srcOffsetY) & ~1; 113072b676d7Smrg pitch = (width + 3) & ~3; 113172b676d7Smrg overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy * pitch; 113272b676d7Smrg overlay.PSU = overlay.PSY + pitch * height; 113372b676d7Smrg overlay.PSV = overlay.PSU + ((((width >> 1) + 3) & ~3) * (height >> 1)); 113472b676d7Smrg overlay.PSY >>= 2; 113572b676d7Smrg overlay.PSV >>= 2; 113672b676d7Smrg overlay.PSU >>= 2; 113772b676d7Smrg break; 113872b676d7Smrg case PIXEL_FMT_YUY2: 113972b676d7Smrg case PIXEL_FMT_UYVY: 114072b676d7Smrg case PIXEL_FMT_RGB6: 114172b676d7Smrg case PIXEL_FMT_RGB5: 114272b676d7Smrg default: 114372b676d7Smrg sx = (pPriv->src_x + srcOffsetX) & ~1; 114472b676d7Smrg sy = (pPriv->src_y + srcOffsetY); 114572b676d7Smrg overlay.PSY = (pPriv->bufAddr[pPriv->currentBuf] + sx*2 + sy*srcPitch); 114672b676d7Smrg overlay.PSY >>= 2; 114772b676d7Smrg break; 114872b676d7Smrg } 114972b676d7Smrg 115072b676d7Smrg /* FIXME: Is this correct? (Is it required to set the end address? 115172b676d7Smrg * Datasheet is not clear) - (reg does not exist on 530/620) 115272b676d7Smrg */ 115372b676d7Smrg overlay.YUVEnd = (pPriv->bufAddr[pPriv->currentBuf] + pPriv->totalSize) >> 14; 115472b676d7Smrg 115572b676d7Smrg /* FIXME: is it possible that srcW < 0 */ 115672b676d7Smrg overlay.srcW = pPriv->src_w - (sx - pPriv->src_x); 115772b676d7Smrg overlay.srcH = pPriv->src_h - (sy - pPriv->src_y); 115872b676d7Smrg 115972b676d7Smrg if( (pPriv->oldx1 != overlay.dstBox.x1) || 116072b676d7Smrg (pPriv->oldx2 != overlay.dstBox.x2) || 116172b676d7Smrg (pPriv->oldy1 != overlay.dstBox.y1) || 116272b676d7Smrg (pPriv->oldy2 != overlay.dstBox.y2) ) { 116372b676d7Smrg pPriv->mustwait = 1; 116472b676d7Smrg pPriv->oldx1 = overlay.dstBox.x1; pPriv->oldx2 = overlay.dstBox.x2; 116572b676d7Smrg pPriv->oldy1 = overlay.dstBox.y1; pPriv->oldy2 = overlay.dstBox.y2; 116672b676d7Smrg } 116772b676d7Smrg 116872b676d7Smrg /* calculate line buffer length */ 116972b676d7Smrg calc_line_buf_size(&overlay); 117072b676d7Smrg 117172b676d7Smrg overlay.VBlankActiveFunc = vblank_active_CRT1; 117272b676d7Smrg/* overlay.GetScanLineFunc = get_scanline_CRT1; */ 117372b676d7Smrg 117472b676d7Smrg /* calculate scale factor */ 117572b676d7Smrg calc_scale_factor(pSiS, &overlay, pScrn, pPriv); 117672b676d7Smrg 117772b676d7Smrg /* set (not only determine) if line buffer is to be merged */ 117872b676d7Smrg if(pSiS->oldChipset > OC_SIS5597) { 117972b676d7Smrg int temp = 384; 118072b676d7Smrg if(pSiS->oldChipset <= OC_SIS6326) temp = 352; 118172b676d7Smrg merge_line_buf(pSiS, pPriv, (overlay.srcW > temp)); 118272b676d7Smrg } 118372b676d7Smrg 118472b676d7Smrg /* set overlay */ 118572b676d7Smrg set_overlay(pSiS, &overlay, pPriv, index); 118672b676d7Smrg 118772b676d7Smrg /* enable overlay */ 118872b676d7Smrg if(pSiS->oldChipset > OC_SIS6326) { 118972b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40); 119072b676d7Smrg } 119172b676d7Smrg setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x02, 0x02); 119272b676d7Smrg 119372b676d7Smrg pPriv->mustwait = 0; 119472b676d7Smrg} 119572b676d7Smrg 119672b676d7Smrgstatic void 119772b676d7SmrgSIS6326StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 119872b676d7Smrg{ 119972b676d7Smrg SISPortPrivPtr pPriv = (SISPortPrivPtr)data; 120072b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 120172b676d7Smrg 120272b676d7Smrg if(pPriv->grabbedByV4L) return; 120372b676d7Smrg 120472b676d7Smrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 120572b676d7Smrg 120672b676d7Smrg if(shutdown) { 120772b676d7Smrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 120872b676d7Smrg close_overlay(pSiS, pPriv); 120972b676d7Smrg pPriv->mustwait = 1; 121072b676d7Smrg } 121172b676d7Smrg SISFreeFBMemory(pScrn, &pPriv->handle); 121272b676d7Smrg pPriv->videoStatus = 0; 121372b676d7Smrg pSiS->VideoTimerCallback = NULL; 121472b676d7Smrg } else { 121572b676d7Smrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 121672b676d7Smrg pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON; 121772b676d7Smrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 121872b676d7Smrg pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; 121972b676d7Smrg } 122072b676d7Smrg } 122172b676d7Smrg} 122272b676d7Smrg 122372b676d7Smrgstatic int 122472b676d7SmrgSIS6326PutImage( 122572b676d7Smrg ScrnInfoPtr pScrn, 122672b676d7Smrg short src_x, short src_y, 122772b676d7Smrg short drw_x, short drw_y, 122872b676d7Smrg short src_w, short src_h, 122972b676d7Smrg short drw_w, short drw_h, 123072b676d7Smrg int id, unsigned char* buf, 123172b676d7Smrg short width, short height, 123272b676d7Smrg Bool sync, 123372b676d7Smrg RegionPtr clipBoxes, pointer data, 123472b676d7Smrg DrawablePtr pDraw 123572b676d7Smrg){ 123672b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 123772b676d7Smrg SISPortPrivPtr pPriv = (SISPortPrivPtr)data; 123872b676d7Smrg int totalSize=0; 123972b676d7Smrg CARD32 *src, *dest; 124072b676d7Smrg unsigned long i; 124172b676d7Smrg 124272b676d7Smrg if(pPriv->grabbedByV4L) return Success; 124372b676d7Smrg 124472b676d7Smrg pPriv->drw_x = drw_x; 124572b676d7Smrg pPriv->drw_y = drw_y; 124672b676d7Smrg pPriv->drw_w = drw_w; 124772b676d7Smrg pPriv->drw_h = drw_h; 124872b676d7Smrg pPriv->src_x = src_x; 124972b676d7Smrg pPriv->src_y = src_y; 125072b676d7Smrg pPriv->src_w = src_w; 125172b676d7Smrg pPriv->src_h = src_h; 125272b676d7Smrg pPriv->id = id; 125372b676d7Smrg pPriv->height = height; 125472b676d7Smrg pPriv->width = width; 125572b676d7Smrg 125672b676d7Smrg /* Pixel formats: 125772b676d7Smrg 1. YU12: 3 planes: H V 125872b676d7Smrg Y sample period 1 1 (8 bit per pixel) 125972b676d7Smrg V sample period 2 2 (8 bit per pixel, subsampled) 126072b676d7Smrg U sample period 2 2 (8 bit per pixel, subsampled) 126172b676d7Smrg 126272b676d7Smrg Y plane is fully sampled (width*height), U and V planes 126372b676d7Smrg are sampled in 2x2 blocks, hence a group of 4 pixels requires 126472b676d7Smrg 4 + 1 + 1 = 6 bytes. The data is planar, ie in single planes 126572b676d7Smrg for Y, U and V. 126672b676d7Smrg 2. UYVY: 3 planes: H V 126772b676d7Smrg Y sample period 1 1 (8 bit per pixel) 126872b676d7Smrg V sample period 2 1 (8 bit per pixel, subsampled) 126972b676d7Smrg U sample period 2 1 (8 bit per pixel, subsampled) 127072b676d7Smrg Y plane is fully sampled (width*height), U and V planes 127172b676d7Smrg are sampled in 2x1 blocks, hence a group of 4 pixels requires 127272b676d7Smrg 4 + 2 + 2 = 8 bytes. The data is bit packed, there are no separate 127372b676d7Smrg Y, U or V planes. 127472b676d7Smrg Bit order: U0 Y0 V0 Y1 U2 Y2 V2 Y3 ... 127572b676d7Smrg 3. I420: Like YU12, but planes U and V are in reverse order. 127672b676d7Smrg 4. YUY2: Like UYVY, but order is 127772b676d7Smrg Y0 U0 Y1 V0 Y2 U2 Y3 V2 ... 127872b676d7Smrg */ 127972b676d7Smrg 128072b676d7Smrg switch(id){ 128172b676d7Smrg case PIXEL_FMT_YV12: 128272b676d7Smrg case PIXEL_FMT_I420: 128372b676d7Smrg pPriv->srcPitch = (width + 7) & ~7; 128472b676d7Smrg /* Size = width * height * 3 / 2 */ 128572b676d7Smrg totalSize = (pPriv->srcPitch * height * 3) >> 1; 128672b676d7Smrg break; 128772b676d7Smrg case PIXEL_FMT_YUY2: 128872b676d7Smrg case PIXEL_FMT_UYVY: 128972b676d7Smrg case PIXEL_FMT_RGB5: 129072b676d7Smrg case PIXEL_FMT_RGB6: 129172b676d7Smrg default: 129272b676d7Smrg pPriv->srcPitch = ((width << 1) + 3) & ~3; 129372b676d7Smrg /* Size = width * 2 * height */ 129472b676d7Smrg totalSize = pPriv->srcPitch * height; 129572b676d7Smrg } 129672b676d7Smrg 129772b676d7Smrg /* make it a multiple of 16 to simplify to copy loop */ 129872b676d7Smrg totalSize += 15; 129972b676d7Smrg totalSize &= ~15; /* in bytes */ 130072b676d7Smrg 130172b676d7Smrg pPriv->totalSize = totalSize; 130272b676d7Smrg 130372b676d7Smrg /* allocate memory (we do doublebuffering) - size is in bytes */ 130472b676d7Smrg if(!(pPriv->bufAddr[0] = SISAllocateFBMemory(pScrn, &pPriv->handle, totalSize << 1))) 130572b676d7Smrg return BadAlloc; 130672b676d7Smrg 130772b676d7Smrg pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; 130872b676d7Smrg 130972b676d7Smrg /* copy data */ 131072b676d7Smrg if((pSiS->XvUseMemcpy) || (totalSize < 16)) { 131172b676d7Smrg SiSMemCopyToVideoRam(pSiS, pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); 131272b676d7Smrg } else { 131372b676d7Smrg dest = (CARD32 *)(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf]); 131472b676d7Smrg src = (CARD32 *)buf; 131572b676d7Smrg for(i = 0; i < (totalSize/16); i++) { 131672b676d7Smrg *dest++ = *src++; 131772b676d7Smrg *dest++ = *src++; 131872b676d7Smrg *dest++ = *src++; 131972b676d7Smrg *dest++ = *src++; 132072b676d7Smrg } 132172b676d7Smrg } 132272b676d7Smrg 132372b676d7Smrg SIS6326DisplayVideo(pScrn, pPriv); 132472b676d7Smrg 132572b676d7Smrg /* update cliplist */ 132672b676d7Smrg if( pPriv->autopaintColorKey && 132772b676d7Smrg (pPriv->grabbedByV4L || 132872b676d7Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,3,0) 132972b676d7Smrg !RegionsEqual(&pPriv->clip, clipBoxes)) ) { 133072b676d7Smrg#else 133172b676d7Smrg !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) ) { 133272b676d7Smrg#endif 133372b676d7Smrg /* We always paint colorkey for V4L */ 133472b676d7Smrg if(!pPriv->grabbedByV4L) 133572b676d7Smrg REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 133672b676d7Smrg /* draw these */ 133772b676d7Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,1,99,1,0) 133872b676d7Smrg (*pSiS->AccelInfoPtr->FillSolidRects)(pScrn, pPriv->colorKey, GXcopy, ~0, 133972b676d7Smrg REGION_NUM_RECTS(clipBoxes), 134072b676d7Smrg REGION_RECTS(clipBoxes)); 134172b676d7Smrg#else 134272b676d7Smrg xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 134372b676d7Smrg#endif 134472b676d7Smrg } 134572b676d7Smrg 134672b676d7Smrg pPriv->currentBuf ^= 1; 134772b676d7Smrg 134872b676d7Smrg pPriv->videoStatus = CLIENT_VIDEO_ON; 134972b676d7Smrg 135072b676d7Smrg pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; 135172b676d7Smrg 135272b676d7Smrg return Success; 135372b676d7Smrg} 135472b676d7Smrg 135572b676d7Smrgstatic int 135672b676d7SmrgSIS6326QueryImageAttributes( 135772b676d7Smrg ScrnInfoPtr pScrn, 135872b676d7Smrg int id, 135972b676d7Smrg unsigned short *w, unsigned short *h, 136072b676d7Smrg int *pitches, int *offsets 136172b676d7Smrg){ 136272b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 136372b676d7Smrg int pitchY, pitchUV; 136472b676d7Smrg int size, sizeY, sizeUV; 136572b676d7Smrg 136672b676d7Smrg if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH; 136772b676d7Smrg if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT; 136872b676d7Smrg 136972b676d7Smrg if(pSiS->oldChipset < OC_SIS6326) { 137072b676d7Smrg if(*w > IMAGE_MAX_WIDTH_5597) *w = IMAGE_MAX_WIDTH_5597; 137172b676d7Smrg if(*h > IMAGE_MAX_HEIGHT_5597) *h = IMAGE_MAX_HEIGHT_5597; 137272b676d7Smrg } else { 137372b676d7Smrg if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; 137472b676d7Smrg if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; 137572b676d7Smrg } 137672b676d7Smrg 137772b676d7Smrg switch(id) { 137872b676d7Smrg case PIXEL_FMT_YV12: 137972b676d7Smrg case PIXEL_FMT_I420: 138072b676d7Smrg *w = (*w + 7) & ~7; 138172b676d7Smrg *h = (*h + 1) & ~1; 138272b676d7Smrg pitchY = *w; 138372b676d7Smrg pitchUV = *w >> 1; 138472b676d7Smrg if(pitches) { 138572b676d7Smrg pitches[0] = pitchY; 138672b676d7Smrg pitches[1] = pitches[2] = pitchUV; 138772b676d7Smrg } 138872b676d7Smrg sizeY = pitchY * (*h); 138972b676d7Smrg sizeUV = pitchUV * ((*h) >> 1); 139072b676d7Smrg if(offsets) { 139172b676d7Smrg offsets[0] = 0; 139272b676d7Smrg offsets[1] = sizeY; 139372b676d7Smrg offsets[2] = sizeY + sizeUV; 139472b676d7Smrg } 139572b676d7Smrg size = sizeY + (sizeUV << 1); 139672b676d7Smrg break; 139772b676d7Smrg case PIXEL_FMT_YUY2: 139872b676d7Smrg case PIXEL_FMT_UYVY: 139972b676d7Smrg case PIXEL_FMT_RGB5: 140072b676d7Smrg case PIXEL_FMT_RGB6: 140172b676d7Smrg default: 140272b676d7Smrg *w = (*w + 1) & ~1; 140372b676d7Smrg pitchY = *w << 1; 140472b676d7Smrg if(pitches) pitches[0] = pitchY; 140572b676d7Smrg if(offsets) offsets[0] = 0; 140672b676d7Smrg size = pitchY * (*h); 140772b676d7Smrg break; 140872b676d7Smrg } 140972b676d7Smrg 141072b676d7Smrg return size; 141172b676d7Smrg} 141272b676d7Smrg 141372b676d7Smrgstatic void 141472b676d7SmrgSIS6326VideoTimerCallback(ScrnInfoPtr pScrn, Time now) 141572b676d7Smrg{ 141672b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 141772b676d7Smrg SISPortPrivPtr pPriv = NULL; 141872b676d7Smrg unsigned char sridx, cridx; 141972b676d7Smrg 142072b676d7Smrg pSiS->VideoTimerCallback = NULL; 142172b676d7Smrg 142272b676d7Smrg if(!pScrn->vtSema) return; 142372b676d7Smrg 142472b676d7Smrg if(pSiS->adaptor) { 142572b676d7Smrg pPriv = GET_PORT_PRIVATE(pScrn); 142672b676d7Smrg if(!pPriv->videoStatus) pPriv = NULL; 142772b676d7Smrg } 142872b676d7Smrg 142972b676d7Smrg if(pPriv) { 143072b676d7Smrg if(pPriv->videoStatus & TIMER_MASK) { 143172b676d7Smrg if(pPriv->videoStatus & OFF_TIMER) { 143272b676d7Smrg if(pPriv->offTime < now) { 143372b676d7Smrg /* Turn off the overlay */ 143472b676d7Smrg sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); 143572b676d7Smrg close_overlay(pSiS, pPriv); 143672b676d7Smrg outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); 143772b676d7Smrg pPriv->mustwait = 1; 143872b676d7Smrg pPriv->videoStatus = FREE_TIMER; 143972b676d7Smrg pPriv->freeTime = now + FREE_DELAY; 144072b676d7Smrg pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; 144172b676d7Smrg } 144272b676d7Smrg } else if(pPriv->videoStatus & FREE_TIMER) { 144372b676d7Smrg if(pPriv->freeTime < now) { 144472b676d7Smrg SISFreeFBMemory(pScrn, &pPriv->handle); 144572b676d7Smrg pPriv->mustwait = 1; 144672b676d7Smrg pPriv->videoStatus = 0; 144772b676d7Smrg } 144872b676d7Smrg } else 144972b676d7Smrg pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; 145072b676d7Smrg } 145172b676d7Smrg } 145272b676d7Smrg} 145372b676d7Smrg 145472b676d7Smrg/* Offscreen surface stuff for v4l */ 145572b676d7Smrg 145672b676d7Smrgstatic int 145772b676d7SmrgSIS6326AllocSurface ( 145872b676d7Smrg ScrnInfoPtr pScrn, 145972b676d7Smrg int id, 146072b676d7Smrg unsigned short w, 146172b676d7Smrg unsigned short h, 146272b676d7Smrg XF86SurfacePtr surface 146372b676d7Smrg) 146472b676d7Smrg{ 146572b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 146672b676d7Smrg SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 146772b676d7Smrg int size; 146872b676d7Smrg 146972b676d7Smrg if((w < IMAGE_MIN_WIDTH) || (h < IMAGE_MIN_HEIGHT)) 147072b676d7Smrg return BadValue; 147172b676d7Smrg 147272b676d7Smrg if(pSiS->oldChipset < OC_SIS6326) { 147372b676d7Smrg if((w > IMAGE_MAX_WIDTH_5597) || (h > IMAGE_MAX_HEIGHT_5597)) 147472b676d7Smrg return BadValue; 147572b676d7Smrg } else { 147672b676d7Smrg if((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) 147772b676d7Smrg return BadValue; 147872b676d7Smrg } 147972b676d7Smrg 148072b676d7Smrg if(pPriv->grabbedByV4L) 148172b676d7Smrg return BadAlloc; 148272b676d7Smrg 148372b676d7Smrg w = (w + 1) & ~1; 148472b676d7Smrg pPriv->pitch = ((w << 1) + 63) & ~63; /* Only packed pixel modes supported */ 148572b676d7Smrg size = h * pPriv->pitch; 148672b676d7Smrg if(!(pPriv->offset = SISAllocateFBMemory(pScrn, &pPriv->handle, size))) 148772b676d7Smrg return BadAlloc; 148872b676d7Smrg 148972b676d7Smrg pPriv->totalSize = size; 149072b676d7Smrg 149172b676d7Smrg surface->width = w; 149272b676d7Smrg surface->height = h; 149372b676d7Smrg surface->pScrn = pScrn; 149472b676d7Smrg surface->id = id; 149572b676d7Smrg surface->pitches = &pPriv->pitch; 149672b676d7Smrg surface->offsets = &pPriv->offset; 149772b676d7Smrg surface->devPrivate.ptr = (pointer)pPriv; 149872b676d7Smrg 149972b676d7Smrg close_overlay(pSiS, pPriv); 150072b676d7Smrg pPriv->videoStatus = 0; 150172b676d7Smrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 150272b676d7Smrg pSiS->VideoTimerCallback = NULL; 150372b676d7Smrg pPriv->grabbedByV4L = TRUE; 150472b676d7Smrg return Success; 150572b676d7Smrg} 150672b676d7Smrg 150772b676d7Smrgstatic int 150872b676d7SmrgSIS6326StopSurface (XF86SurfacePtr surface) 150972b676d7Smrg{ 151072b676d7Smrg SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); 151172b676d7Smrg SISPtr pSiS = SISPTR(surface->pScrn); 151272b676d7Smrg 151372b676d7Smrg if(pPriv->grabbedByV4L && pPriv->videoStatus) { 151472b676d7Smrg close_overlay(pSiS, pPriv); 151572b676d7Smrg pPriv->mustwait = 1; 151672b676d7Smrg pPriv->videoStatus = 0; 151772b676d7Smrg } 151872b676d7Smrg return Success; 151972b676d7Smrg} 152072b676d7Smrg 152172b676d7Smrgstatic int 152272b676d7SmrgSIS6326FreeSurface (XF86SurfacePtr surface) 152372b676d7Smrg{ 152472b676d7Smrg SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); 152572b676d7Smrg 152672b676d7Smrg if(pPriv->grabbedByV4L) { 152772b676d7Smrg SIS6326StopSurface(surface); 152872b676d7Smrg SISFreeFBMemory(surface->pScrn, &pPriv->handle); 152972b676d7Smrg pPriv->grabbedByV4L = FALSE; 153072b676d7Smrg } 153172b676d7Smrg return Success; 153272b676d7Smrg} 153372b676d7Smrg 153472b676d7Smrgstatic int 153572b676d7SmrgSIS6326GetSurfaceAttribute ( 153672b676d7Smrg ScrnInfoPtr pScrn, 153772b676d7Smrg Atom attribute, 153872b676d7Smrg INT32 *value 153972b676d7Smrg) 154072b676d7Smrg{ 154172b676d7Smrg SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 154272b676d7Smrg 154372b676d7Smrg return SIS6326GetPortAttribute(pScrn, attribute, value, (pointer)pPriv); 154472b676d7Smrg} 154572b676d7Smrg 154672b676d7Smrgstatic int 154772b676d7SmrgSIS6326SetSurfaceAttribute( 154872b676d7Smrg ScrnInfoPtr pScrn, 154972b676d7Smrg Atom attribute, 155072b676d7Smrg INT32 value 155172b676d7Smrg) 155272b676d7Smrg{ 155372b676d7Smrg SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);; 155472b676d7Smrg 155572b676d7Smrg return SIS6326SetPortAttribute(pScrn, attribute, value, (pointer)pPriv); 155672b676d7Smrg} 155772b676d7Smrg 155872b676d7Smrgstatic int 155972b676d7SmrgSIS6326DisplaySurface ( 156072b676d7Smrg XF86SurfacePtr surface, 156172b676d7Smrg short src_x, short src_y, 156272b676d7Smrg short drw_x, short drw_y, 156372b676d7Smrg short src_w, short src_h, 156472b676d7Smrg short drw_w, short drw_h, 156572b676d7Smrg RegionPtr clipBoxes 156672b676d7Smrg) 156772b676d7Smrg{ 156872b676d7Smrg ScrnInfoPtr pScrn = surface->pScrn; 156972b676d7Smrg SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); 157072b676d7Smrg 157172b676d7Smrg if(!pPriv->grabbedByV4L) 157272b676d7Smrg return Success; 157372b676d7Smrg 157472b676d7Smrg pPriv->drw_x = drw_x; 157572b676d7Smrg pPriv->drw_y = drw_y; 157672b676d7Smrg pPriv->drw_w = drw_w; 157772b676d7Smrg pPriv->drw_h = drw_h; 157872b676d7Smrg pPriv->src_x = src_x; 157972b676d7Smrg pPriv->src_y = src_y; 158072b676d7Smrg pPriv->src_w = src_w; 158172b676d7Smrg pPriv->src_h = src_h; 158272b676d7Smrg pPriv->id = surface->id; 158372b676d7Smrg pPriv->height = surface->height; 158472b676d7Smrg pPriv->bufAddr[0] = surface->offsets[0]; 158572b676d7Smrg pPriv->currentBuf = 0; 158672b676d7Smrg pPriv->srcPitch = surface->pitches[0]; 158772b676d7Smrg 158872b676d7Smrg SIS6326DisplayVideo(pScrn, pPriv); 158972b676d7Smrg 159072b676d7Smrg if(pPriv->autopaintColorKey) { 159172b676d7Smrg#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,1,99,1,0) 159272b676d7Smrg (*XAAPTR(pScrn)->FillSolidRects)(pScrn, pPriv->colorKey, GXcopy, ~0, 159372b676d7Smrg REGION_NUM_RECTS(clipBoxes), 159472b676d7Smrg REGION_RECTS(clipBoxes)); 159572b676d7Smrg#else 159672b676d7Smrg xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 159772b676d7Smrg#endif 159872b676d7Smrg } 159972b676d7Smrg 160072b676d7Smrg pPriv->videoStatus = CLIENT_VIDEO_ON; 160172b676d7Smrg 160272b676d7Smrg return Success; 160372b676d7Smrg} 160472b676d7Smrg 160572b676d7SmrgXF86OffscreenImageRec SIS6326OffscreenImages[2] = 160672b676d7Smrg{ 160772b676d7Smrg { 160872b676d7Smrg &SIS6326Images[0], /* YUV2 */ 160972b676d7Smrg VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 161072b676d7Smrg SIS6326AllocSurface, 161172b676d7Smrg SIS6326FreeSurface, 161272b676d7Smrg SIS6326DisplaySurface, 161372b676d7Smrg SIS6326StopSurface, 161472b676d7Smrg SIS6326GetSurfaceAttribute, 161572b676d7Smrg SIS6326SetSurfaceAttribute, 161672b676d7Smrg IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, 161772b676d7Smrg NUM_ATTRIBUTES, 161872b676d7Smrg &SIS6326Attributes[0] /* Support all attributes */ 161972b676d7Smrg }, 162072b676d7Smrg { 162172b676d7Smrg &SIS6326Images[1], /* UYVY */ 162272b676d7Smrg VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 162372b676d7Smrg SIS6326AllocSurface, 162472b676d7Smrg SIS6326FreeSurface, 162572b676d7Smrg SIS6326DisplaySurface, 162672b676d7Smrg SIS6326StopSurface, 162772b676d7Smrg SIS6326GetSurfaceAttribute, 162872b676d7Smrg SIS6326SetSurfaceAttribute, 162972b676d7Smrg IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, 163072b676d7Smrg NUM_ATTRIBUTES, 163172b676d7Smrg &SIS6326Attributes[0] /* Support all attributes */ 163272b676d7Smrg }, 163372b676d7Smrg}; 163472b676d7Smrg 163572b676d7Smrgstatic void 163672b676d7SmrgSIS6326InitOffscreenImages(ScreenPtr pScrn) 163772b676d7Smrg{ 163872b676d7Smrg xf86XVRegisterOffscreenImages(pScrn, SIS6326OffscreenImages, 2); 163972b676d7Smrg} 164072b676d7Smrg 164172b676d7Smrg 164272b676d7Smrg 164372b676d7Smrg 1644