pm2_video.c revision 4f6cd06f
1c35d236eSmrg/* 2c35d236eSmrg * Permedia 2 Xv Driver 3c35d236eSmrg * 4c35d236eSmrg * Copyright (C) 1998-2000 Michael H. Schimek <m.schimek@netway.at> 5c35d236eSmrg * 6c35d236eSmrg * Permission is hereby granted, free of charge, to any person obtaining a copy 7c35d236eSmrg * of this software and associated documentation files (the "Software"), to deal 8c35d236eSmrg * in the Software without restriction, including without limitation the rights 9c35d236eSmrg * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10c35d236eSmrg * copies of the Software, and to permit persons to whom the Software is 11c35d236eSmrg * furnished to do so, subject to the following conditions: 12c35d236eSmrg * 13c35d236eSmrg * The above copyright notice and this permission notice shall be included in 14c35d236eSmrg * all copies or substantial portions of the Software. 15c35d236eSmrg * 16c35d236eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17c35d236eSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18c35d236eSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19c35d236eSmrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20c35d236eSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21c35d236eSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22c35d236eSmrg */ 23c35d236eSmrg 24c35d236eSmrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_video.c,v 1.25tsi Exp $ */ 25c35d236eSmrg 26c35d236eSmrg#ifdef HAVE_CONFIG_H 27c35d236eSmrg#include "config.h" 28c35d236eSmrg#endif 29c35d236eSmrg 30c35d236eSmrg#include "xf86.h" 31c35d236eSmrg#include "xf86_OSproc.h" 32c35d236eSmrg#include "xf86Pci.h" 33c35d236eSmrg#include "xf86PciInfo.h" 34c35d236eSmrg#include "xf86fbman.h" 35c35d236eSmrg#include "xf86i2c.h" 36c35d236eSmrg#include "xf86xv.h" 37c35d236eSmrg#include <X11/extensions/Xv.h> 38c35d236eSmrg 39c35d236eSmrg#include "glint_regs.h" 40c35d236eSmrg#include "glint.h" 41c35d236eSmrg#include <sys/types.h> 42c35d236eSmrg#include <sys/stat.h> 43c35d236eSmrg#include <fcntl.h> 444f6cd06fSmrg#include <sys/ioctl.h> 454f6cd06fSmrg#include <unistd.h> 46c35d236eSmrg 47c35d236eSmrg#undef MIN 48c35d236eSmrg#undef ABS 49c35d236eSmrg#undef CLAMP 50c35d236eSmrg#undef ENTRIES 51c35d236eSmrg 52c35d236eSmrg#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 53c35d236eSmrg#define ABS(n) (((n) < 0) ? -(n) : (n)) 54c35d236eSmrg#define CLAMP(v, min, max) (((v) < (min)) ? (min) : MIN(v, max)) 55c35d236eSmrg#define ENTRIES(array) (sizeof(array) / sizeof((array)[0])) 56c35d236eSmrg 57c35d236eSmrg#define ADAPTORS 3 58c35d236eSmrg#define PORTS 6 59c35d236eSmrg 60c35d236eSmrg#define PCI_SUBSYSTEM_ID_WINNER_2000_P2C 0x0a311048 61c35d236eSmrg#define PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2C 0x0a321048 62c35d236eSmrg#define PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2A 0x0a351048 63c35d236eSmrg#define PCI_SUBSYSTEM_ID_WINNER_2000_P2A 0x0a441048 64c35d236eSmrg 65c35d236eSmrg/* 66c35d236eSmrg * Proprietary kernel backbone interface 67c35d236eSmrg */ 68c35d236eSmrg 69c35d236eSmrg#define XVIPC_MAGIC 0x6A5D70E6 70c35d236eSmrg#define XVIPC_VERSION 1 71c35d236eSmrg#define VIDIOC_PM2_XVIPC 0x00007F7F 72c35d236eSmrg 73c35d236eSmrgtypedef enum { 74c35d236eSmrg OP_ATTR = 0, 75c35d236eSmrg OP_RESET = 8, /* unused */ 76c35d236eSmrg OP_START, 77c35d236eSmrg OP_STOP, 78c35d236eSmrg OP_PLUG, 79c35d236eSmrg OP_VIDEOSTD, 80c35d236eSmrg OP_WINDOW, /* unused */ 81c35d236eSmrg OP_CONNECT, 82c35d236eSmrg OP_EVENT, 83c35d236eSmrg OP_ALLOC, 84c35d236eSmrg OP_FREE, 85c35d236eSmrg OP_UPDATE, 86c35d236eSmrg OP_NOP, /* ignored */ 87c35d236eSmrg OP_ENTER, 88c35d236eSmrg OP_LEAVE, 89c35d236eSmrg OP_DISCONNECT 90c35d236eSmrg} xvipc_op; 91c35d236eSmrg 92c35d236eSmrgtypedef struct _pm2_xvipc { 93c35d236eSmrg int magic; 94c35d236eSmrg void *pm2p, *pAPriv; 95c35d236eSmrg int port, op, time, block; 96c35d236eSmrg int a, b, c, d, e, f; 97c35d236eSmrg} pm2_xvipc; 98c35d236eSmrg 99c35d236eSmrgstatic pm2_xvipc xvipc; 100c35d236eSmrgstatic int xvipc_fd = -1; 101c35d236eSmrg 102c35d236eSmrg 103c35d236eSmrg#define MAX_BUFFERS 2 104c35d236eSmrg 105c35d236eSmrgtypedef struct { 106c35d236eSmrg CARD32 xy, wh; /* 16.0 16.0 */ 107c35d236eSmrg INT32 s, t; /* 12.20 fp */ 108c35d236eSmrg short y1, y2; 109c35d236eSmrg} CookieRec, *CookiePtr; 110c35d236eSmrg 111c35d236eSmrgtypedef struct _PortPrivRec { 112c35d236eSmrg struct _AdaptorPrivRec * pAdaptor; 113c35d236eSmrg I2CDevRec I2CDev; 114c35d236eSmrg 115c35d236eSmrg INT32 Attribute[8]; /* Brig, Con, Sat, Hue, Int, Filt, BkgCol, Alpha */ 116c35d236eSmrg 117c35d236eSmrg int BuffersRequested; 118c35d236eSmrg int BuffersAllocated; 119c35d236eSmrg FBAreaPtr pFBArea[MAX_BUFFERS]; 120c35d236eSmrg CARD32 BufferBase[MAX_BUFFERS]; /* FB byte offset */ 121c35d236eSmrg CARD32 BufferStride; /* bytes */ 122c35d236eSmrg CARD32 BufferPProd; /* PProd(BufferStride in buffer pixels) */ 123c35d236eSmrg 124c35d236eSmrg INT32 vx, vy, vw, vh; /* 12.10 fp */ 125c35d236eSmrg int dx, dy, dw, dh; 126c35d236eSmrg int fw, fh; 127c35d236eSmrg 128c35d236eSmrg CookiePtr pCookies; 129c35d236eSmrg int nCookies; 130c35d236eSmrg INT32 dS, dT; /* 12.20 fp */ 131c35d236eSmrg 132c35d236eSmrg int Id, Bpp; /* Scaler */ 133c35d236eSmrg 134c35d236eSmrg int Plug; 135c35d236eSmrg int BkgCol; /* RGB 5:6:5; 5:6:5 */ 136c35d236eSmrg Bool StreamOn; /* buffer <-> hardware */ 137c35d236eSmrg int VideoOn; /* buffer <-> screen */ 138c35d236eSmrg int VideoStdReq; 139c35d236eSmrg 140c35d236eSmrg int StopDelay; 141c35d236eSmrg 142c35d236eSmrg int FramesPerSec, FrameAcc; 143c35d236eSmrg 144c35d236eSmrg} PortPrivRec, *PortPrivPtr; 145c35d236eSmrg 146c35d236eSmrgenum { VIDEO_OFF, VIDEO_ONE_SHOT, VIDEO_ON }; 147c35d236eSmrg 148c35d236eSmrgtypedef struct _LFBAreaRec { 149c35d236eSmrg struct _LFBAreaRec * Next; 150c35d236eSmrg int Linear; 151c35d236eSmrg FBAreaPtr pFBArea; 152c35d236eSmrg} LFBAreaRec, *LFBAreaPtr; 153c35d236eSmrg 154c35d236eSmrgtypedef struct _AdaptorPrivRec { 155c35d236eSmrg struct _AdaptorPrivRec * Next; 156c35d236eSmrg ScrnInfoPtr pScrn; 157c35d236eSmrg 158c35d236eSmrg void * pm2p; 159c35d236eSmrg LFBAreaPtr LFBList; 160c35d236eSmrg 161c35d236eSmrg CARD32 dFifoControl; 162c35d236eSmrg CARD32 dDitherMode; 163c35d236eSmrg CARD32 dAlphaBlendMode; 164c35d236eSmrg CARD32 dTextureDataFormat; 165c35d236eSmrg 166c35d236eSmrg OsTimerPtr Timer; 167c35d236eSmrg int TimerUsers; 168c35d236eSmrg int Delay, Instant; 169c35d236eSmrg 170c35d236eSmrg int FramesPerSec; 171c35d236eSmrg int FrameLines; 172c35d236eSmrg int IntLine; /* Frame, not field */ 173c35d236eSmrg int LinePer; /* nsec */ 174c35d236eSmrg 175c35d236eSmrg Bool VideoIO; 176c35d236eSmrg int VideoStd; 177c35d236eSmrg 178c35d236eSmrg PortPrivRec Port[PORTS]; 179c35d236eSmrg 180c35d236eSmrg} AdaptorPrivRec, *AdaptorPrivPtr; 181c35d236eSmrg 182c35d236eSmrgstatic AdaptorPrivPtr AdaptorPrivList = NULL; 183c35d236eSmrg 184c35d236eSmrg#define FreeCookies(pPPriv) \ 185c35d236eSmrgdo { \ 186c35d236eSmrg if ((pPPriv)->pCookies) { \ 187c35d236eSmrg xfree((pPPriv)->pCookies); \ 188c35d236eSmrg (pPPriv)->pCookies = NULL; \ 189c35d236eSmrg } \ 190c35d236eSmrg} while (0) 191c35d236eSmrg 192c35d236eSmrg#define PORTNUM(p) ((int)((p) - &pAPriv->Port[0])) 193c35d236eSmrg#define BPPSHIFT(g) (2 - (g)->BppShift) /* Bytes per pixel = 1 << BPPSHIFT(pGlint) */ 194c35d236eSmrg 195c35d236eSmrg#define DEBUG(x) 196c35d236eSmrg 197c35d236eSmrgstatic const Bool ColorBars = FALSE; 198c35d236eSmrg 199c35d236eSmrg 200c35d236eSmrg/* 201c35d236eSmrg * XF86Config VideoAdaptor options 202c35d236eSmrg */ 203c35d236eSmrg 204c35d236eSmrgtypedef enum { 205c35d236eSmrg OPTION_DEVICE, 206c35d236eSmrg OPTION_FPS, 207c35d236eSmrg OPTION_BUFFERS, 208c35d236eSmrg OPTION_ENCODING, 209c35d236eSmrg OPTION_EXPOSE /* obsolete, ignored */ 210c35d236eSmrg} OptToken; 211c35d236eSmrg 212c35d236eSmrg/* XXX These should be made const, and per-screen/adaptor copies processed. */ 213c35d236eSmrgstatic OptionInfoRec AdaptorOptions[] = { 214c35d236eSmrg { OPTION_DEVICE, "Device", OPTV_STRING, {0}, FALSE }, 215c35d236eSmrg { -1, NULL, OPTV_NONE, {0}, FALSE } 216c35d236eSmrg}; 217c35d236eSmrgstatic OptionInfoRec InputOptions[] = { 218c35d236eSmrg { OPTION_BUFFERS, "Buffers", OPTV_INTEGER, {0}, FALSE }, 219c35d236eSmrg { OPTION_FPS, "FramesPerSec", OPTV_INTEGER, {0}, FALSE }, 220c35d236eSmrg { OPTION_ENCODING, "Encoding", OPTV_STRING, {0}, FALSE }, 221c35d236eSmrg { -1, NULL, OPTV_NONE, {0}, FALSE } 222c35d236eSmrg}; 223c35d236eSmrgstatic OptionInfoRec OutputOptions[] = { 224c35d236eSmrg { OPTION_BUFFERS, "Buffers", OPTV_INTEGER, {0}, FALSE }, 225c35d236eSmrg { OPTION_EXPOSE, "Expose", OPTV_BOOLEAN, {0}, FALSE }, 226c35d236eSmrg { OPTION_FPS, "FramesPerSec", OPTV_INTEGER, {0}, FALSE }, 227c35d236eSmrg { OPTION_ENCODING, "Encoding", OPTV_STRING, {0}, FALSE }, 228c35d236eSmrg { -1, NULL, OPTV_NONE, {0}, FALSE } 229c35d236eSmrg}; 230c35d236eSmrg 231c35d236eSmrg 232c35d236eSmrg/* 233c35d236eSmrg * Attributes 234c35d236eSmrg */ 235c35d236eSmrg 236c35d236eSmrg#define XV_ENCODING "XV_ENCODING" 237c35d236eSmrg#define XV_BRIGHTNESS "XV_BRIGHTNESS" 238c35d236eSmrg#define XV_CONTRAST "XV_CONTRAST" 239c35d236eSmrg#define XV_SATURATION "XV_SATURATION" 240c35d236eSmrg#define XV_HUE "XV_HUE" 241c35d236eSmrg 242c35d236eSmrg/* Proprietary */ 243c35d236eSmrg 244c35d236eSmrg#define XV_INTERLACE "XV_INTERLACE" /* Interlaced (bool) */ 245c35d236eSmrg#define XV_FILTER "XV_FILTER" /* Bilinear filter (bool) */ 246c35d236eSmrg#define XV_BKGCOLOR "XV_BKGCOLOR" /* Output background (0x00RRGGBB) */ 247c35d236eSmrg#define XV_ALPHA "XV_ALPHA" /* Scaler alpha channel (bool) */ 248c35d236eSmrg 249c35d236eSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 250c35d236eSmrg 251c35d236eSmrgstatic Atom xvEncoding, xvBrightness, xvContrast, xvSaturation, xvHue; 252c35d236eSmrgstatic Atom xvInterlace, xvFilter, xvBkgColor, xvAlpha; 253c35d236eSmrg 254c35d236eSmrg/* Input */ 255c35d236eSmrg 256c35d236eSmrgstatic XF86VideoEncodingRec 257c35d236eSmrgInputVideoEncodings[] = 258c35d236eSmrg{ 259c35d236eSmrg { 0, "pal-composite", 704, 576, { 1, 50 }}, 260c35d236eSmrg { 1, "pal-composite_adaptor", 704, 576, { 1, 50 }}, 261c35d236eSmrg { 2, "pal-svideo", 704, 576, { 1, 50 }}, 262c35d236eSmrg { 3, "ntsc-composite", 704, 480, { 1001, 60000 }}, 263c35d236eSmrg { 4, "ntsc-composite_adaptor", 704, 480, { 1001, 60000 }}, 264c35d236eSmrg { 5, "ntsc-svideo", 704, 480, { 1001, 60000 }}, 265c35d236eSmrg { 6, "secam-composite", 704, 576, { 1, 50 }}, 266c35d236eSmrg { 7, "secam-composite_adaptor", 704, 576, { 1, 50 }}, 267c35d236eSmrg { 8, "secam-svideo", 704, 576, { 1, 50 }}, 268c35d236eSmrg}; 269c35d236eSmrg 270c35d236eSmrgstatic XF86AttributeRec 271c35d236eSmrgInputVideoAttributes[] = 272c35d236eSmrg{ 273c35d236eSmrg { XvSettable | XvGettable, -1000, +1000, XV_BRIGHTNESS }, 274c35d236eSmrg { XvSettable | XvGettable, -3000, +1000, XV_CONTRAST }, 275c35d236eSmrg { XvSettable | XvGettable, -3000, +1000, XV_SATURATION }, 276c35d236eSmrg { XvSettable | XvGettable, -1000, +1000, XV_HUE }, 277c35d236eSmrg { XvSettable | XvGettable, 0, 2, XV_INTERLACE }, 278c35d236eSmrg { XvSettable | XvGettable, 0, 1, XV_FILTER }, 279c35d236eSmrg}; 280c35d236eSmrg 281c35d236eSmrgstatic XF86VideoFormatRec 282c35d236eSmrgInputVideoFormats[] = 283c35d236eSmrg{ 284c35d236eSmrg { 8, TrueColor }, /* Dithered */ 285c35d236eSmrg { 15, TrueColor }, 286c35d236eSmrg { 16, TrueColor }, 287c35d236eSmrg { 24, TrueColor }, 288c35d236eSmrg}; 289c35d236eSmrg 290c35d236eSmrg/* Output */ 291c35d236eSmrg 292c35d236eSmrgstatic XF86VideoEncodingRec 293c35d236eSmrgOutputVideoEncodings[] = 294c35d236eSmrg{ 295c35d236eSmrg { 0, "pal-composite_adaptor", 704, 576, { 1, 50 }}, 296c35d236eSmrg { 1, "pal-svideo", 704, 576, { 1, 50 }}, 297c35d236eSmrg { 2, "ntsc-composite_adaptor", 704, 480, { 1001, 60000 }}, 298c35d236eSmrg { 3, "ntsc-svideo", 704, 480, { 1001, 60000 }}, 299c35d236eSmrg}; 300c35d236eSmrg 301c35d236eSmrgstatic XF86AttributeRec 302c35d236eSmrgOutputVideoAttributes[] = 303c35d236eSmrg{ 304c35d236eSmrg { XvSettable | XvGettable, 0, 2, XV_INTERLACE }, 305c35d236eSmrg { XvSettable | XvGettable, 0, 1, XV_FILTER }, 306c35d236eSmrg { XvSettable | XvGettable, 0x000000, 0xFFFFFF, XV_BKGCOLOR }, 307c35d236eSmrg}; 308c35d236eSmrg 309c35d236eSmrgstatic XF86VideoFormatRec 310c35d236eSmrgOutputVideoFormats[] = 311c35d236eSmrg{ 312c35d236eSmrg { 8, TrueColor }, 313c35d236eSmrg { 8, PseudoColor }, /* Using .. */ 314c35d236eSmrg { 8, StaticColor }, 315c35d236eSmrg { 8, GrayScale }, 316c35d236eSmrg { 8, StaticGray }, /* .. TexelLUT */ 317c35d236eSmrg { 15, TrueColor }, 318c35d236eSmrg { 16, TrueColor }, 319c35d236eSmrg { 24, TrueColor }, 320c35d236eSmrg}; 321c35d236eSmrg 322c35d236eSmrg/* Scaler */ 323c35d236eSmrg 324c35d236eSmrgstatic XF86VideoEncodingRec 325c35d236eSmrgScalerEncodings[] = 326c35d236eSmrg{ 327c35d236eSmrg { 0, "XV_IMAGE", 2047, 2047, { 1, 1 }}, 328c35d236eSmrg}; 329c35d236eSmrg 330c35d236eSmrgstatic XF86AttributeRec 331c35d236eSmrgScalerAttributes[] = 332c35d236eSmrg{ 333c35d236eSmrg { XvSettable | XvGettable, 0, 1, XV_FILTER }, 334c35d236eSmrg { XvSettable | XvGettable, 0, 1, XV_ALPHA }, 335c35d236eSmrg}; 336c35d236eSmrg 337c35d236eSmrg#define ScalerVideoFormats InputVideoFormats 338c35d236eSmrg 339c35d236eSmrg/* 340c35d236eSmrg * FOURCC from http://www.webartz.com/fourcc 341c35d236eSmrg * Generic GUID for legacy FOURCC XXXXXXXX-0000-0010-8000-00AA00389B71 342c35d236eSmrg */ 343c35d236eSmrg#define LE4CC(a,b,c,d) (((CARD32)(a)&0xFF)|(((CARD32)(b)&0xFF)<<8)|(((CARD32)(c)&0xFF)<<16)|(((CARD32)(d)&0xFF)<<24)) 344c35d236eSmrg#define GUID4CC(a,b,c,d) { a,b,c,d,0,0,0,0x10,0x80,0,0,0xAA,0,0x38,0x9B,0x71 } 345c35d236eSmrg 346c35d236eSmrg#define NoOrder LSBFirst 347c35d236eSmrg 348c35d236eSmrgstatic XF86ImageRec 349c35d236eSmrgScalerImages[] = 350c35d236eSmrg{ 351c35d236eSmrg /* Planar YVU 4:2:0 (emulated) */ 352c35d236eSmrg { LE4CC('Y','V','1','2'), XvYUV, NoOrder, GUID4CC('Y','V','1','2'), 353c35d236eSmrg 12, XvPlanar, 3, 0, 0, 0, 0, 354c35d236eSmrg 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU", XvTopToBottom }, 355c35d236eSmrg 356c35d236eSmrg /* Packed YUYV 4:2:2 */ 357c35d236eSmrg { LE4CC('Y','U','Y','2'), XvYUV, NoOrder, GUID4CC('Y','U','Y','2'), 358c35d236eSmrg 16, XvPacked, 1, 0, 0, 0, 0, 359c35d236eSmrg 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUYV", XvTopToBottom }, 360c35d236eSmrg 361c35d236eSmrg /* Packed UYVY 4:2:2 */ 362c35d236eSmrg { LE4CC('U','Y','V','Y'), XvYUV, NoOrder, GUID4CC('U','Y','V','Y'), 363c35d236eSmrg 16, XvPacked, 1, 0, 0, 0, 0, 364c35d236eSmrg 8, 8, 8, 1, 2, 2, 1, 1, 1, "UYVY", XvTopToBottom }, 365c35d236eSmrg 366c35d236eSmrg /* Packed YUVA 4:4:4 */ 367c35d236eSmrg { LE4CC('Y','U','V','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, 368c35d236eSmrg 32, XvPacked, 1, 0, 0, 0, 0, 369c35d236eSmrg 8, 8, 8, 1, 1, 1, 1, 1, 1, "YUVA", XvTopToBottom }, 370c35d236eSmrg 371c35d236eSmrg /* Packed VUYA 4:4:4 */ 372c35d236eSmrg { LE4CC('V','U','Y','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, 373c35d236eSmrg 32, XvPacked, 1, 0, 0, 0, 0, 374c35d236eSmrg 8, 8, 8, 1, 1, 1, 1, 1, 1, "VUYA", XvTopToBottom }, 375c35d236eSmrg 376c35d236eSmrg /* RGBA 8:8:8:8 */ 377c35d236eSmrg { 0x41, XvRGB, LSBFirst, { 0 }, 378c35d236eSmrg 32, XvPacked, 1, 24, 0x0000FF, 0x00FF00, 0xFF0000, 379c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, 380c35d236eSmrg 381c35d236eSmrg /* RGB 5:6:5 */ 382c35d236eSmrg { 0x42, XvRGB, LSBFirst, { 0 }, 383c35d236eSmrg 16, XvPacked, 1, 16, 0x001F, 0x07E0, 0xF800, 384c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, 385c35d236eSmrg 386c35d236eSmrg /* RGBA 5:5:5:1 */ 387c35d236eSmrg { 0x43, XvRGB, LSBFirst, { 0 }, 388c35d236eSmrg 16, XvPacked, 1, 15, 0x001F, 0x03E0, 0x7C00, 389c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, 390c35d236eSmrg 391c35d236eSmrg /* RGBA 4:4:4:4 */ 392c35d236eSmrg { 0x44, XvRGB, LSBFirst, { 0 }, 393c35d236eSmrg 16, XvPacked, 1, 12, 0x000F, 0x00F0, 0x0F00, 394c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, 395c35d236eSmrg 396c35d236eSmrg /* RGBA 2:3:2:1 */ 397c35d236eSmrg { 0x45, XvRGB, NoOrder, { 0 }, 398c35d236eSmrg 8, XvPacked, 1, 7, 0x03, 0x1C, 0x60, 399c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, 400c35d236eSmrg 401c35d236eSmrg /* RGB 3:3:2 */ 402c35d236eSmrg { 0x46, XvRGB, NoOrder, { 0 }, 403c35d236eSmrg 8, XvPacked, 1, 8, 0x07, 0x38, 0xC0, 404c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, 405c35d236eSmrg 406c35d236eSmrg /* BGRA 8:8:8:8 */ 407c35d236eSmrg { 0x47, XvRGB, LSBFirst, { 0 }, 408c35d236eSmrg 32, XvPacked, 1, 24, 0xFF0000, 0x00FF00, 0x0000FF, 409c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, 410c35d236eSmrg 411c35d236eSmrg /* BGR 5:6:5 */ 412c35d236eSmrg { 0x48, XvRGB, LSBFirst, { 0 }, 413c35d236eSmrg 16, XvPacked, 1, 16, 0xF800, 0x07E0, 0x001F, 414c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, 415c35d236eSmrg 416c35d236eSmrg /* BGRA 5:5:5:1 */ 417c35d236eSmrg { 0x49, XvRGB, LSBFirst, { 0 }, 418c35d236eSmrg 16, XvPacked, 1, 15, 0x7C00, 0x03E0, 0x001F, 419c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, 420c35d236eSmrg 421c35d236eSmrg /* BGRA 4:4:4:4 */ 422c35d236eSmrg { 0x4A, XvRGB, LSBFirst, { 0 }, 423c35d236eSmrg 16, XvPacked, 1, 12, 0x0F00, 0x00F0, 0x000F, 424c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, 425c35d236eSmrg 426c35d236eSmrg /* BGRA 2:3:2:1 */ 427c35d236eSmrg { 0x4B, XvRGB, NoOrder, { 0 }, 428c35d236eSmrg 8, XvPacked, 1, 7, 0x60, 0x1C, 0x03, 429c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, 430c35d236eSmrg 431c35d236eSmrg /* BGR 2:3:3 */ 432c35d236eSmrg { 0x4C, XvRGB, NoOrder, { 0 }, 433c35d236eSmrg 8, XvPacked, 1, 8, 0xC0, 0x38, 0x07, 434c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, 435c35d236eSmrg}; 436c35d236eSmrg 437c35d236eSmrg 438c35d236eSmrg/* 439c35d236eSmrg * Video codec tables 440c35d236eSmrg */ 441c35d236eSmrg 442c35d236eSmrg#define SAA7111_SLAVE_ADDRESS 0x48 443c35d236eSmrg#define SAA7125_SLAVE_ADDRESS 0x88 444c35d236eSmrg 445c35d236eSmrgstatic I2CByte 446c35d236eSmrgDecInitVec[] = 447c35d236eSmrg{ 448c35d236eSmrg 0x11, 0x00, 449c35d236eSmrg 0x02, 0xC1, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 450c35d236eSmrg 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x4A, 451c35d236eSmrg 0x0A, 0x80, 0x0B, 0x40, 0x0C, 0x40, 0x0D, 0x00, 452c35d236eSmrg 0x0E, 0x01, 0x10, 0xC8, 0x12, 0x20, 453c35d236eSmrg 0x13, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 454c35d236eSmrg}; 455c35d236eSmrg 456c35d236eSmrgstatic I2CByte 457c35d236eSmrgEncInitVec[] = 458c35d236eSmrg{ 459c35d236eSmrg 0x3A, 0x83, 0x61, 0xC2, 460c35d236eSmrg 0x5A, 119, 0x5B, 0x7D, 461c35d236eSmrg 0x5C, 0xAF, 0x5D, 0x3C, 0x5E, 0x3F, 0x5F, 0x3F, 462c35d236eSmrg 0x60, 0x70, 0x62, 0x4B, 0x67, 0x00, 463c35d236eSmrg 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, 0x20, 464c35d236eSmrg 0x6C, 0x03, 0x6D, 0x30, 0x6E, 0xA0, 0x6F, 0x00, 465c35d236eSmrg 0x70, 0x80, 0x71, 0xE8, 0x72, 0x10, 466c35d236eSmrg 0x7A, 0x13, 0x7B, 0xFB, 0x7C, 0x00, 0x7D, 0x00, 467c35d236eSmrg}; 468c35d236eSmrg 469c35d236eSmrgstatic I2CByte Dec02[3] = { 0xC1, 0xC0, 0xC4 }; 470c35d236eSmrgstatic I2CByte Dec09[3] = { 0x4A, 0x4A, 0xCA }; 471c35d236eSmrgstatic I2CByte Enc3A[3] = { 0x03, 0x03, 0x23 }; 472c35d236eSmrgstatic I2CByte Enc61[3] = { 0x06, 0x01, 0xC2 }; 473c35d236eSmrg 474c35d236eSmrgstatic I2CByte 475c35d236eSmrgDecVS[3][8] = 476c35d236eSmrg{ 477c35d236eSmrg { 0x06, 108, 0x07, 108, 0x08, 0x09, 0x0E, 0x01 }, 478c35d236eSmrg { 0x06, 107, 0x07, 107, 0x08, 0x49, 0x0E, 0x01 }, 479c35d236eSmrg { 0x06, 108, 0x07, 108, 0x08, 0x01, 0x0E, 0x51 } 480c35d236eSmrg}; 481c35d236eSmrg 482c35d236eSmrg#define FSC(n) ((CARD32)((n) / 27e6 * 4294967296.0 + .5)) 483c35d236eSmrg#define SUBCARRIER_FREQ_PAL (4.433619e6) 484c35d236eSmrg#define SUBCARRIER_FREQ_NTSC (3.579545e6) 485c35d236eSmrg 486c35d236eSmrgstatic I2CByte 487c35d236eSmrgEncVS[2][14] = 488c35d236eSmrg{ 489c35d236eSmrg { 0x62, 0x4B, 0x6B, 0x28, 0x6E, 0xA0, 490c35d236eSmrg 0x63, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 0), 491c35d236eSmrg 0x64, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 8), 492c35d236eSmrg 0x65, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 16), 493c35d236eSmrg 0x66, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 24) }, 494c35d236eSmrg { 0x62, 0x6A, 0x6B, 0x20, 0x6E, 0x20, 495c35d236eSmrg 0x63, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 0), 496c35d236eSmrg 0x64, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 8), 497c35d236eSmrg 0x65, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 16), 498c35d236eSmrg 0x66, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 24) } 499c35d236eSmrg}; 500c35d236eSmrg 501c35d236eSmrg/* Forward */ 502c35d236eSmrgstatic void StopVideoStream(PortPrivPtr pPPriv, Bool shutdown); 503c35d236eSmrgstatic void RestoreVideoStd(AdaptorPrivPtr pAPriv); 504c35d236eSmrgstatic Bool xvipcHandshake(PortPrivPtr pPPriv, int op, Bool block); 505c35d236eSmrg 506c35d236eSmrg 507c35d236eSmrg/* 508c35d236eSmrg * Video codec controls 509c35d236eSmrg */ 510c35d236eSmrg 511c35d236eSmrgstatic int 512c35d236eSmrgSetAttr(PortPrivPtr pPPriv, int i, int value) 513c35d236eSmrg{ 514c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 515c35d236eSmrg int v; 516c35d236eSmrg 517c35d236eSmrg if (value < InputVideoAttributes[i].min_value) 518c35d236eSmrg value = InputVideoAttributes[i].min_value; 519c35d236eSmrg else 520c35d236eSmrg if (value > InputVideoAttributes[i].max_value) 521c35d236eSmrg value = InputVideoAttributes[i].max_value; 522c35d236eSmrg 523c35d236eSmrg switch (i) { 524c35d236eSmrg case 0: 525c35d236eSmrg v = 128 + (MIN(value, 999) * 128) / 1000; 526c35d236eSmrg break; 527c35d236eSmrg 528c35d236eSmrg case 1: 529c35d236eSmrg case 2: 530c35d236eSmrg v = 64 + (MIN(value, 999) * 64) / 1000; 531c35d236eSmrg break; 532c35d236eSmrg 533c35d236eSmrg default: 534c35d236eSmrg v = (MIN(value, 999) * 128) / 1000; 535c35d236eSmrg break; 536c35d236eSmrg } 537c35d236eSmrg 538c35d236eSmrg if (pAPriv->pm2p) { 539c35d236eSmrg xvipc.a = v << 8; 540c35d236eSmrg 541c35d236eSmrg if (!xvipcHandshake(pPPriv, OP_ATTR + i, TRUE)) 542c35d236eSmrg return XvBadAlloc; 543c35d236eSmrg } else 544c35d236eSmrg if (!xf86I2CWriteByte(&pPPriv->I2CDev, 0x0A + i, v)) 545c35d236eSmrg return XvBadAlloc; 546c35d236eSmrg 547c35d236eSmrg pPPriv->Attribute[i] = value; 548c35d236eSmrg 549c35d236eSmrg return Success; 550c35d236eSmrg} 551c35d236eSmrg 552c35d236eSmrgstatic int 553c35d236eSmrgSetPlug(PortPrivPtr pPPriv, int Plug) 554c35d236eSmrg{ 555c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 556c35d236eSmrg 557c35d236eSmrg if (pAPriv->pm2p) { 558c35d236eSmrg xvipc.a = Plug - (pPPriv == &pAPriv->Port[1]); 559c35d236eSmrg 560c35d236eSmrg if (!xvipcHandshake(pPPriv, OP_PLUG, TRUE)) 561c35d236eSmrg return XvBadAlloc; 562c35d236eSmrg } else { 563c35d236eSmrg if (pPPriv == &pAPriv->Port[0]) { 564c35d236eSmrg if (!xf86I2CWriteByte(&pPPriv->I2CDev, 0x02, Dec02[Plug]) || 565c35d236eSmrg !xf86I2CWriteByte(&pPPriv->I2CDev, 0x09, Dec09[Plug])) 566c35d236eSmrg return XvBadAlloc; 567c35d236eSmrg } else { 568c35d236eSmrg if (pPPriv->StreamOn) { 569c35d236eSmrg if (!xf86I2CWriteByte(&pPPriv->I2CDev, 0x3A, Enc3A[Plug])) 570c35d236eSmrg return XvBadAlloc; 571c35d236eSmrg } else 572c35d236eSmrg if (ColorBars) 573c35d236eSmrg xf86I2CWriteByte(&pPPriv->I2CDev, 0x3A, 0x83); 574c35d236eSmrg } 575c35d236eSmrg } 576c35d236eSmrg 577c35d236eSmrg pPPriv->Plug = Plug; 578c35d236eSmrg 579c35d236eSmrg return Success; 580c35d236eSmrg} 581c35d236eSmrg 582c35d236eSmrgenum { PAL, NTSC, SECAM }; 583c35d236eSmrg 584c35d236eSmrgstatic int 585c35d236eSmrgSetVideoStd(PortPrivPtr pPPriv, int VideoStd) 586c35d236eSmrg{ 587c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 588c35d236eSmrg int r = Success; 589c35d236eSmrg 590c35d236eSmrg if (pAPriv->pm2p) { 591c35d236eSmrg xvipc.a = VideoStd; 592c35d236eSmrg 593c35d236eSmrg if (!xvipcHandshake(&pAPriv->Port[0], OP_VIDEOSTD, TRUE)) 594c35d236eSmrg return XvBadAlloc; 595c35d236eSmrg 596c35d236eSmrg VideoStd = xvipc.a; /* Actual */ 597c35d236eSmrg } else { 598c35d236eSmrg if (VideoStd == SECAM) 599c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2); 600c35d236eSmrg /* Disable output, SECAM not supported */ 601c35d236eSmrg 602c35d236eSmrg if (!xf86I2CWriteVec(&pAPriv->Port[0].I2CDev, &DecVS[VideoStd][0], 4)) { 603c35d236eSmrg pAPriv->VideoStd = -1; 604c35d236eSmrg return XvBadAlloc; 605c35d236eSmrg } 606c35d236eSmrg 607c35d236eSmrg if (VideoStd != SECAM) 608c35d236eSmrg if (!xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, &EncVS[VideoStd][0], 7)) { 609c35d236eSmrg pAPriv->VideoStd = -1; 610c35d236eSmrg return XvBadAlloc; 611c35d236eSmrg } 612c35d236eSmrg } 613c35d236eSmrg 614c35d236eSmrg pAPriv->VideoStd = VideoStd; 615c35d236eSmrg pPPriv->VideoStdReq = VideoStd; 616c35d236eSmrg 617c35d236eSmrg if (VideoStd == NTSC) { 618c35d236eSmrg pAPriv->FramesPerSec = 30; 619c35d236eSmrg pAPriv->FrameLines = 525; 620c35d236eSmrg pAPriv->IntLine = 513; 621c35d236eSmrg pAPriv->LinePer = 63555; 622c35d236eSmrg } else { 623c35d236eSmrg pAPriv->FramesPerSec = 25; 624c35d236eSmrg pAPriv->FrameLines = 625; 625c35d236eSmrg pAPriv->IntLine = 613; 626c35d236eSmrg pAPriv->LinePer = 64000; 627c35d236eSmrg } 628c35d236eSmrg 629c35d236eSmrg#if 0 /* XF86Config option */ 630c35d236eSmrg 631c35d236eSmrg pAPriv->Port[0].FramesPerSec = pAPriv->FramesPerSec; 632c35d236eSmrg pAPriv->Port[1].FramesPerSec = pAPriv->FramesPerSec; 633c35d236eSmrg 634c35d236eSmrg#endif 635c35d236eSmrg 636c35d236eSmrg return r; 637c35d236eSmrg} 638c35d236eSmrg 639c35d236eSmrg 640c35d236eSmrg/* 641c35d236eSmrg * Buffer management 642c35d236eSmrg */ 643c35d236eSmrg 644c35d236eSmrgstatic void 645c35d236eSmrgRemoveAreaCallback(FBAreaPtr pFBArea) 646c35d236eSmrg{ 647c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) pFBArea->devPrivate.ptr; 648c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 649c35d236eSmrg DEBUG(ScrnInfoPtr pScrn = pAPriv->pScrn;) 650c35d236eSmrg int i; 651c35d236eSmrg 652c35d236eSmrg for (i = 0; i < MAX_BUFFERS && pPPriv->pFBArea[i] != pFBArea; i++); 653c35d236eSmrg 654c35d236eSmrg if (i >= MAX_BUFFERS) 655c35d236eSmrg return; 656c35d236eSmrg 657c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, 658c35d236eSmrg "RemoveAreaCallback port #%d, buffer #%d, pFB=%p, off=0x%08x\n", 659c35d236eSmrg PORTNUM(pPPriv), i, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); 660c35d236eSmrg 661c35d236eSmrg if (pAPriv->VideoIO && PORTNUM(pPPriv) < 2) { 662c35d236eSmrg StopVideoStream(pPPriv, FALSE); 663c35d236eSmrg } 664c35d236eSmrg 665c35d236eSmrg for (; i < MAX_BUFFERS - 1; i++) 666c35d236eSmrg pPPriv->pFBArea[i] = pPPriv->pFBArea[i + 1]; 667c35d236eSmrg 668c35d236eSmrg pPPriv->pFBArea[MAX_BUFFERS - 1] = NULL; 669c35d236eSmrg 670c35d236eSmrg pPPriv->BuffersAllocated--; 671c35d236eSmrg} 672c35d236eSmrg 673c35d236eSmrgstatic void 674c35d236eSmrgRemoveableBuffers(PortPrivPtr pPPriv, Bool remove) 675c35d236eSmrg{ 676c35d236eSmrg int i; 677c35d236eSmrg 678c35d236eSmrg for (i = 0; i < MAX_BUFFERS; i++) 679c35d236eSmrg if (pPPriv->pFBArea[i]) 680c35d236eSmrg pPPriv->pFBArea[i]->RemoveAreaCallback = 681c35d236eSmrg remove ? RemoveAreaCallback : NULL; 682c35d236eSmrg} 683c35d236eSmrg 684c35d236eSmrgstatic void 685c35d236eSmrgFreeBuffers(PortPrivPtr pPPriv) 686c35d236eSmrg{ 687c35d236eSmrg DEBUG(AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;) 688c35d236eSmrg DEBUG(ScrnInfoPtr pScrn = pAPriv->pScrn;) 689c35d236eSmrg int i; 690c35d236eSmrg 691c35d236eSmrg RemoveableBuffers(pPPriv, FALSE); 692c35d236eSmrg 693c35d236eSmrg for (i = MAX_BUFFERS - 1; i >= 0; i--) 694c35d236eSmrg if (pPPriv->pFBArea[i]) { 695c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, 696c35d236eSmrg "FreeBuffers port #%d, buffer #%d, pFB=%p, off=0x%08x\n", 697c35d236eSmrg PORTNUM(pPPriv), i, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); 698c35d236eSmrg 699c35d236eSmrg xf86FreeOffscreenArea(pPPriv->pFBArea[i]); 700c35d236eSmrg 701c35d236eSmrg pPPriv->pFBArea[i] = NULL; 702c35d236eSmrg } 703c35d236eSmrg 704c35d236eSmrg pPPriv->BuffersAllocated = 0; 705c35d236eSmrg} 706c35d236eSmrg 707c35d236eSmrgenum { FORCE_LINEAR = 1, FORCE_RECT }; 708c35d236eSmrg 709c35d236eSmrgstatic int 710c35d236eSmrgAllocateBuffers(PortPrivPtr pPPriv, 711c35d236eSmrg int w, int h, int bytespp, 712c35d236eSmrg int num, int force) 713c35d236eSmrg{ 714c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 715c35d236eSmrg ScrnInfoPtr pScrn = pAPriv->pScrn; 716c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 717c35d236eSmrg Bool linear = (force != FORCE_RECT); 718c35d236eSmrg int i, j, retry = 0; 719c35d236eSmrg 720c35d236eSmrg FreeBuffers(pPPriv); 721c35d236eSmrg 722c35d236eSmrg for (i = 0; i < num; i++) { 723c35d236eSmrg if (linear) { 724c35d236eSmrg for (j = (w + 31) >> 5; partprodPermedia[j] < 0; j++); 725c35d236eSmrg 726c35d236eSmrg pPPriv->BufferStride = j * bytespp * 32; 727c35d236eSmrg pPPriv->BufferPProd = partprodPermedia[j]; 728c35d236eSmrg 729c35d236eSmrg pPPriv->pFBArea[i] = xf86AllocateLinearOffscreenArea(pScrn->pScreen, 730c35d236eSmrg (pPPriv->BufferStride * h + (1 << BPPSHIFT(pGlint)) - 1) >> BPPSHIFT(pGlint), 731c35d236eSmrg 8 >> BPPSHIFT(pGlint), NULL, NULL, (pointer) pPPriv); 732c35d236eSmrg 733c35d236eSmrg if (pPPriv->pFBArea[i]) 734c35d236eSmrg /* pPPriv->BufferBase[i] = pPPriv->pFBArea[i].linear; */ 735c35d236eSmrg pPPriv->BufferBase[i] = 736c35d236eSmrg ((pPPriv->pFBArea[i]->box.y1 * pScrn->displayWidth) + 737c35d236eSmrg pPPriv->pFBArea[i]->box.x1) << BPPSHIFT(pGlint); 738c35d236eSmrg 739c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, 740c35d236eSmrg "New linear buffer %dx%d, rec %dx%d -> pFB=%p, off=0x%08x\n", 741c35d236eSmrg w, h, pPPriv->BufferStride, h, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); 742c35d236eSmrg } else { 743c35d236eSmrg pPPriv->BufferStride = pScrn->displayWidth << BPPSHIFT(pGlint); 744c35d236eSmrg 745c35d236eSmrg j = pPPriv->BufferStride / bytespp; 746c35d236eSmrg 747c35d236eSmrg if (j <= w && j <= 2048 && (j & 31) == 0 && 748c35d236eSmrg partprodPermedia[j >> 5] >= 0) 749c35d236eSmrg { 750c35d236eSmrg pPPriv->BufferPProd = partprodPermedia[j >> 5]; 751c35d236eSmrg pPPriv->pFBArea[i] = xf86AllocateOffscreenArea(pScrn->pScreen, 752c35d236eSmrg w, h, 8 >> BPPSHIFT(pGlint), NULL, NULL, (pointer) pPPriv); 753c35d236eSmrg 754c35d236eSmrg if (pPPriv->pFBArea[i]) 755c35d236eSmrg pPPriv->BufferBase[i] = 756c35d236eSmrg ((pPPriv->pFBArea[i]->box.y1 * pScrn->displayWidth) + 757c35d236eSmrg pPPriv->pFBArea[i]->box.x1) << BPPSHIFT(pGlint); 758c35d236eSmrg 759c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, 760c35d236eSmrg "New rect buffer %dx%d, stride %d, %d -> pFB=%p, off=0x%08x\n", 761c35d236eSmrg w, h, pPPriv->BufferStride, j, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); 762c35d236eSmrg } 763c35d236eSmrg } 764c35d236eSmrg 765c35d236eSmrg if (pPPriv->pFBArea[i]) 766c35d236eSmrg continue; 767c35d236eSmrg 768c35d236eSmrg if (!force && i == 0 && retry++ < 1) { 769c35d236eSmrg linear ^= TRUE; 770c35d236eSmrg i = -1; 771c35d236eSmrg } else 772c35d236eSmrg break; 773c35d236eSmrg } 774c35d236eSmrg 775c35d236eSmrg return pPPriv->BuffersAllocated = i; 776c35d236eSmrg} 777c35d236eSmrg 778c35d236eSmrg 779c35d236eSmrg/* 780c35d236eSmrg * Blitter 781c35d236eSmrg */ 782c35d236eSmrg 783c35d236eSmrgstatic Bool 784c35d236eSmrgRemakePutCookies(PortPrivPtr pPPriv, RegionPtr pRegion) 785c35d236eSmrg{ 786c35d236eSmrg BoxPtr pBox; 787c35d236eSmrg CookiePtr pCookie; 788c35d236eSmrg int nBox; 789c35d236eSmrg 790c35d236eSmrg if (!pRegion) { 791c35d236eSmrg pBox = (BoxPtr) NULL; 792c35d236eSmrg nBox = pPPriv->nCookies; 793c35d236eSmrg } else { 794c35d236eSmrg pBox = REGION_RECTS(pRegion); 795c35d236eSmrg nBox = REGION_NUM_RECTS(pRegion); 796c35d236eSmrg 797c35d236eSmrg if (!pPPriv->pCookies || pPPriv->nCookies < nBox) { 798c35d236eSmrg if (!(pCookie = (CookiePtr) xrealloc(pPPriv->pCookies, nBox * sizeof(CookieRec)))) 799c35d236eSmrg return FALSE; 800c35d236eSmrg 801c35d236eSmrg pPPriv->pCookies = pCookie; 802c35d236eSmrg } 803c35d236eSmrg } 804c35d236eSmrg 805c35d236eSmrg pPPriv->dS = (pPPriv->vw << 10) / pPPriv->dw; 806c35d236eSmrg pPPriv->dT = (pPPriv->vh << 10) / pPPriv->dh; 807c35d236eSmrg 808c35d236eSmrg for (pCookie = pPPriv->pCookies; nBox--; pCookie++, pBox++) { 809c35d236eSmrg if (pRegion) { 810c35d236eSmrg pCookie->y1 = pBox->y1; 811c35d236eSmrg pCookie->y2 = pBox->x1; 812c35d236eSmrg pCookie->xy = (pBox->y1 << 16) | pBox->x1; 813c35d236eSmrg pCookie->wh = ((pBox->y2 - pBox->y1) << 16) | 814c35d236eSmrg (pBox->x2 - pBox->x1); 815c35d236eSmrg } 816c35d236eSmrg 817c35d236eSmrg pCookie->s = (pPPriv->vx << 10) + (pCookie->y2 - pPPriv->dx) * pPPriv->dS; 818c35d236eSmrg pCookie->t = (pPPriv->vy << 10) + (pCookie->y1 - pPPriv->dy) * pPPriv->dT; 819c35d236eSmrg } 820c35d236eSmrg 821c35d236eSmrg pPPriv->nCookies = pCookie - pPPriv->pCookies; 822c35d236eSmrg 823c35d236eSmrg return TRUE; 824c35d236eSmrg} 825c35d236eSmrg 826c35d236eSmrg#define FORMAT_YUYV ((0 << 5) + (1 << 4) + ((19 & 0x10) << 2) + ((19 & 0x0F) << 0)) 827c35d236eSmrg#define FORMAT_UYVY ((1 << 5) + (1 << 4) + ((19 & 0x10) << 2) + ((19 & 0x0F) << 0)) 828c35d236eSmrg#define FORMAT_YUVA ((0 << 5) + ((18 & 0x10) << 2) + ((18 & 0x0F) << 0)) 829c35d236eSmrg#define FORMAT_VUYA ((1 << 5) + ((18 & 0x10) << 2) + ((18 & 0x0F) << 0)) 830c35d236eSmrg 831c35d236eSmrgstatic void 832c35d236eSmrgPutYUV(PortPrivPtr pPPriv, int BufferBase, 833c35d236eSmrg int format, int bptshift, int alpha) 834c35d236eSmrg{ 835c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 836c35d236eSmrg ScrnInfoPtr pScrn = pAPriv->pScrn; 837c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 838c35d236eSmrg CookiePtr pCookie = pPPriv->pCookies; 839c35d236eSmrg int nCookies = pPPriv->nCookies; 840c35d236eSmrg 841c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "PutYUV %08x %08x\n", 842c35d236eSmrg BufferBase, format)); 843c35d236eSmrg 844c35d236eSmrg if (!nCookies || (GLINT_READ_REG(InFIFOSpace) < 200)) 845c35d236eSmrg return; /* Denial of service fix, N/A for scaler */ 846c35d236eSmrg 847c35d236eSmrg CHECKCLIPPING; 848c35d236eSmrg 849c35d236eSmrg GLINT_WRITE_REG(1 << 16, dY); 850c35d236eSmrg GLINT_WRITE_REG(0, RasterizerMode); 851c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode); 852c35d236eSmrg GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode); 853c35d236eSmrg GLINT_WRITE_REG(pPPriv->dS, dSdx); 854c35d236eSmrg GLINT_WRITE_REG(0, dSdyDom); 855c35d236eSmrg GLINT_WRITE_REG(0, dTdx); 856c35d236eSmrg GLINT_WRITE_REG(pPPriv->dT, dTdyDom); 857c35d236eSmrg GLINT_WRITE_REG(BufferBase >> bptshift, PMTextureBaseAddress); 858c35d236eSmrg GLINT_WRITE_REG((bptshift << 19) | pPPriv->BufferPProd, PMTextureMapFormat); 859c35d236eSmrg GLINT_WRITE_REG(format, PMTextureDataFormat); 860c35d236eSmrg GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */ 861c35d236eSmrg (11 << 13) | (11 << 9) | /* TextureSize log2 */ 862c35d236eSmrg UNIT_ENABLE, PMTextureReadMode); 863c35d236eSmrg GLINT_WRITE_REG((0 << 4) /* RGB */ | 864c35d236eSmrg (3 << 1) /* Copy */ | 865c35d236eSmrg UNIT_ENABLE, TextureColorMode); 866c35d236eSmrg if (alpha) 867c35d236eSmrg GLINT_WRITE_REG(pAPriv->dAlphaBlendMode, AlphaBlendMode); 868c35d236eSmrg GLINT_WRITE_REG(pAPriv->dDitherMode, DitherMode); 869c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); 870c35d236eSmrg GLINT_WRITE_REG((alpha << 10) | /* ReadDestination */ 871c35d236eSmrg pGlint->pprod, FBReadMode); 872c35d236eSmrg GLINT_WRITE_REG(0xFFFFFFFF, FBHardwareWriteMask); 873c35d236eSmrg GLINT_WRITE_REG(UNIT_ENABLE, YUVMode); 874c35d236eSmrg 875c35d236eSmrg for (; nCookies--; pCookie++) { 876c35d236eSmrg GLINT_WAIT(5); 877c35d236eSmrg GLINT_WRITE_REG(pCookie->xy, RectangleOrigin); 878c35d236eSmrg GLINT_WRITE_REG(pCookie->wh, RectangleSize); 879c35d236eSmrg GLINT_WRITE_REG(pCookie->s, SStart); 880c35d236eSmrg GLINT_WRITE_REG(pCookie->t, TStart); 881c35d236eSmrg GLINT_WRITE_REG(PrimitiveRectangle | 882c35d236eSmrg XPositive | 883c35d236eSmrg YPositive | 884c35d236eSmrg TextureEnable, Render); 885c35d236eSmrg } 886c35d236eSmrg 887c35d236eSmrg pGlint->x = pGlint->y = -1; /* Force reload */ 888c35d236eSmrg pGlint->w = pGlint->h = -1; 889c35d236eSmrg pGlint->ROP = 0xFF; 890c35d236eSmrg pGlint->planemask = 0xFFFFFFFF; 891c35d236eSmrg 892c35d236eSmrg GLINT_WAIT(8); 893c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); 894c35d236eSmrg GLINT_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat); 895c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); 896c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode); 897c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); 898c35d236eSmrg if (alpha) { 899c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); 900c35d236eSmrg GLINT_WRITE_REG(pGlint->pprod, FBReadMode); 901c35d236eSmrg } 902c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, YUVMode); 903c35d236eSmrg} 904c35d236eSmrg 905c35d236eSmrg#define FORMAT_RGB8888 ((0 << 5) + (0 << 4) + ((0 & 0x10) << 2) + ((0 & 0x0F) << 0)) 906c35d236eSmrg#define FORMAT_RGB565 ((0 << 5) + (1 << 4) + ((16 & 0x10) << 2) + ((16 & 0x0F) << 0)) 907c35d236eSmrg#define FORMAT_RGB5551 ((0 << 5) + (0 << 4) + ((1 & 0x10) << 2) + ((1 & 0x0F) << 0)) 908c35d236eSmrg#define FORMAT_RGB4444 ((0 << 5) + (0 << 4) + ((2 & 0x10) << 2) + ((2 & 0x0F) << 0)) 909c35d236eSmrg#define FORMAT_RGB332 ((0 << 5) + (1 << 4) + ((5 & 0x10) << 2) + ((5 & 0x0F) << 0)) 910c35d236eSmrg#define FORMAT_RGB2321 ((0 << 5) + (0 << 4) + ((9 & 0x10) << 2) + ((9 & 0x0F) << 0)) 911c35d236eSmrg#define FORMAT_BGR8888 ((1 << 5) + (0 << 4) + ((0 & 0x10) << 2) + ((0 & 0x0F) << 0)) 912c35d236eSmrg#define FORMAT_BGR565 ((1 << 5) + (1 << 4) + ((16 & 0x10) << 2) + ((16 & 0x0F) << 0)) 913c35d236eSmrg#define FORMAT_BGR5551 ((1 << 5) + (0 << 4) + ((1 & 0x10) << 2) + ((1 & 0x0F) << 0)) 914c35d236eSmrg#define FORMAT_BGR4444 ((1 << 5) + (0 << 4) + ((2 & 0x10) << 2) + ((2 & 0x0F) << 0)) 915c35d236eSmrg#define FORMAT_BGR332 ((1 << 5) + (1 << 4) + ((5 & 0x10) << 2) + ((5 & 0x0F) << 0)) 916c35d236eSmrg#define FORMAT_BGR2321 ((1 << 5) + (0 << 4) + ((9 & 0x10) << 2) + ((9 & 0x0F) << 0)) 917c35d236eSmrg 918c35d236eSmrgstatic void 919c35d236eSmrgPutRGB(PortPrivPtr pPPriv, int BufferBase, int format, int bptshift, int alpha) 920c35d236eSmrg{ 921c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 922c35d236eSmrg ScrnInfoPtr pScrn = pAPriv->pScrn; 923c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 924c35d236eSmrg CookiePtr pCookie = pPPriv->pCookies; 925c35d236eSmrg int nCookies = pPPriv->nCookies; 926c35d236eSmrg 927c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "PutRGB %08x %08x\n", 928c35d236eSmrg BufferBase, format)); 929c35d236eSmrg 930c35d236eSmrg if (!nCookies) 931c35d236eSmrg return; 932c35d236eSmrg 933c35d236eSmrg CHECKCLIPPING; 934c35d236eSmrg 935c35d236eSmrg GLINT_WRITE_REG(1 << 16, dY); 936c35d236eSmrg GLINT_WRITE_REG(0, RasterizerMode); 937c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode); 938c35d236eSmrg GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode); 939c35d236eSmrg GLINT_WRITE_REG(pPPriv->dS, dSdx); 940c35d236eSmrg GLINT_WRITE_REG(0, dSdyDom); 941c35d236eSmrg GLINT_WRITE_REG(0, dTdx); 942c35d236eSmrg GLINT_WRITE_REG(pPPriv->dT, dTdyDom); 943c35d236eSmrg GLINT_WRITE_REG(BufferBase >> bptshift, PMTextureBaseAddress); 944c35d236eSmrg GLINT_WRITE_REG((bptshift << 19) | pPPriv->BufferPProd, PMTextureMapFormat); 945c35d236eSmrg GLINT_WRITE_REG(format, PMTextureDataFormat); 946c35d236eSmrg GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */ 947c35d236eSmrg (11 << 13) | (11 << 9) | /* TextureSize log2 */ 948c35d236eSmrg UNIT_ENABLE, PMTextureReadMode); 949c35d236eSmrg GLINT_WRITE_REG((0 << 4) /* RGB */ | 950c35d236eSmrg (3 << 1) /* Copy */ | 951c35d236eSmrg UNIT_ENABLE, TextureColorMode); 952c35d236eSmrg if (alpha) 953c35d236eSmrg GLINT_WRITE_REG(pAPriv->dAlphaBlendMode, AlphaBlendMode); 954c35d236eSmrg GLINT_WRITE_REG(pAPriv->dDitherMode, DitherMode); 955c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); 956c35d236eSmrg GLINT_WRITE_REG((alpha << 10) | /* ReadDestination */ 957c35d236eSmrg pGlint->pprod, FBReadMode); 958c35d236eSmrg GLINT_WRITE_REG(0xFFFFFFFF, FBHardwareWriteMask); 959c35d236eSmrg 960c35d236eSmrg for (; nCookies--; pCookie++) { 961c35d236eSmrg GLINT_WAIT(5); 962c35d236eSmrg GLINT_WRITE_REG(pCookie->xy, RectangleOrigin); 963c35d236eSmrg GLINT_WRITE_REG(pCookie->wh, RectangleSize); 964c35d236eSmrg GLINT_WRITE_REG(pCookie->s, SStart); 965c35d236eSmrg GLINT_WRITE_REG(pCookie->t, TStart); 966c35d236eSmrg GLINT_WRITE_REG(PrimitiveRectangle | 967c35d236eSmrg XPositive | 968c35d236eSmrg YPositive | 969c35d236eSmrg TextureEnable, Render); 970c35d236eSmrg } 971c35d236eSmrg 972c35d236eSmrg pGlint->x = pGlint->y = -1; /* Force reload */ 973c35d236eSmrg pGlint->w = pGlint->h = -1; 974c35d236eSmrg pGlint->ROP = 0xFF; 975c35d236eSmrg pGlint->planemask = 0xFFFFFFFF; 976c35d236eSmrg 977c35d236eSmrg GLINT_WAIT(7); 978c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); 979c35d236eSmrg GLINT_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat); 980c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); 981c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode); 982c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); 983c35d236eSmrg if (alpha) { 984c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); 985c35d236eSmrg GLINT_WRITE_REG(pGlint->pprod, FBReadMode); 986c35d236eSmrg } 987c35d236eSmrg} 988c35d236eSmrg 989c35d236eSmrgstatic void 990c35d236eSmrgBlackOut(PortPrivPtr pPPriv, RegionPtr pRegion) 991c35d236eSmrg{ 992c35d236eSmrg ScrnInfoPtr pScrn = pPPriv->pAdaptor->pScrn; 993c35d236eSmrg ScreenPtr pScreen = pScrn->pScreen; 994c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 995c35d236eSmrg RegionRec DRegion; 996c35d236eSmrg BoxRec DBox; 997c35d236eSmrg BoxPtr pBox; 998c35d236eSmrg int nBox; 999c35d236eSmrg 1000c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, 1001c35d236eSmrg "BlackOut %d,%d,%d,%d -- %d,%d,%d,%d\n", 1002c35d236eSmrg pPPriv->vx, pPPriv->vy, pPPriv->vw, pPPriv->vh, 1003c35d236eSmrg pPPriv->dx, pPPriv->dy, pPPriv->dw, pPPriv->dh)); 1004c35d236eSmrg 1005c35d236eSmrg DBox.x1 = pPPriv->dx - (pPPriv->vx * pPPriv->dw) / pPPriv->vw; 1006c35d236eSmrg DBox.y1 = pPPriv->dy - (pPPriv->vy * pPPriv->dh) / pPPriv->vh; 1007c35d236eSmrg DBox.x2 = DBox.x1 + (pPPriv->fw * pPPriv->dw) / pPPriv->vw; 1008c35d236eSmrg DBox.y2 = DBox.y1 + (pPPriv->fh * pPPriv->dh) / pPPriv->vh; 1009c35d236eSmrg 1010c35d236eSmrg REGION_INIT(pScreen, &DRegion, &DBox, 1); 1011c35d236eSmrg 1012c35d236eSmrg if (pRegion) 1013c35d236eSmrg REGION_SUBTRACT(pScreen, &DRegion, &DRegion, pRegion); 1014c35d236eSmrg 1015c35d236eSmrg nBox = REGION_NUM_RECTS(&DRegion); 1016c35d236eSmrg pBox = REGION_RECTS(&DRegion); 1017c35d236eSmrg 1018c35d236eSmrg GLINT_WAIT(15); 1019c35d236eSmrg CHECKCLIPPING; 1020c35d236eSmrg 1021c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); 1022c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferPProd, FBReadMode); 1023c35d236eSmrg GLINT_WRITE_REG(0x1, FBReadPixel); /* 16 */ 1024c35d236eSmrg GLINT_WRITE_REG(pPPriv->BkgCol, FBBlockColor); 1025c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferBase[0] >> 1 /* 16 */, FBWindowBase); 1026c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); 1027c35d236eSmrg 1028c35d236eSmrg for (; nBox--; pBox++) { 1029c35d236eSmrg int w = ((pBox->x2 - pBox->x1) * pPPriv->vw + pPPriv->dw) / pPPriv->dw + 1; 1030c35d236eSmrg int h = ((pBox->y2 - pBox->y1) * pPPriv->vh + pPPriv->dh) / pPPriv->dh + 1; 1031c35d236eSmrg int x = ((pBox->x1 - DBox.x1) * pPPriv->vw + (pPPriv->dw >> 1)) / pPPriv->dw; 1032c35d236eSmrg int y = ((pBox->y1 - DBox.y1) * pPPriv->vh + (pPPriv->dh >> 1)) / pPPriv->dh; 1033c35d236eSmrg 1034c35d236eSmrg if ((x + w) > pPPriv->fw) 1035c35d236eSmrg w = pPPriv->fw - x; 1036c35d236eSmrg if ((y + h) > pPPriv->fh) 1037c35d236eSmrg h = pPPriv->fh - y; 1038c35d236eSmrg 1039c35d236eSmrg GLINT_WAIT(3); 1040c35d236eSmrg GLINT_WRITE_REG((y << 16) | x, RectangleOrigin); 1041c35d236eSmrg GLINT_WRITE_REG((h << 16) | w, RectangleSize); 1042c35d236eSmrg GLINT_WRITE_REG(PrimitiveRectangle | 1043c35d236eSmrg XPositive | YPositive | FastFillEnable, Render); 1044c35d236eSmrg } 1045c35d236eSmrg 1046c35d236eSmrg REGION_UNINIT(pScreen, &DRegion); 1047c35d236eSmrg 1048c35d236eSmrg pGlint->x = pGlint->y = -1; /* Force reload */ 1049c35d236eSmrg pGlint->w = pGlint->h = -1; 1050c35d236eSmrg pGlint->ROP = 0xFF; 1051c35d236eSmrg GLINT_WAIT(3); 1052c35d236eSmrg GLINT_WRITE_REG(0, FBWindowBase); 1053c35d236eSmrg GLINT_WRITE_REG(pGlint->pprod, FBReadMode); 1054c35d236eSmrg GLINT_WRITE_REG(pGlint->PixelWidth, FBReadPixel); 1055c35d236eSmrg} 1056c35d236eSmrg 1057c35d236eSmrgstatic Bool 1058c35d236eSmrgRemakeGetCookies(PortPrivPtr pPPriv, RegionPtr pRegion) 1059c35d236eSmrg{ 1060c35d236eSmrg BoxPtr pBox; 1061c35d236eSmrg CookiePtr pCookie; 1062c35d236eSmrg int nBox; 1063c35d236eSmrg int dw1 = pPPriv->dw - 1; 1064c35d236eSmrg int dh1 = pPPriv->dh - 1; 1065c35d236eSmrg 1066c35d236eSmrg if (!pRegion) { 1067c35d236eSmrg pBox = (BoxPtr) NULL; 1068c35d236eSmrg nBox = pPPriv->nCookies; 1069c35d236eSmrg } else { 1070c35d236eSmrg pBox = REGION_RECTS(pRegion); 1071c35d236eSmrg nBox = REGION_NUM_RECTS(pRegion); 1072c35d236eSmrg 1073c35d236eSmrg if (!pPPriv->pCookies || pPPriv->nCookies < nBox) { 1074c35d236eSmrg if (!(pCookie = (CookiePtr) xrealloc(pPPriv->pCookies, nBox * sizeof(CookieRec)))) 1075c35d236eSmrg return FALSE; 1076c35d236eSmrg 1077c35d236eSmrg pPPriv->pCookies = pCookie; 1078c35d236eSmrg } 1079c35d236eSmrg } 1080c35d236eSmrg 1081c35d236eSmrg pPPriv->dS = (pPPriv->dw << 20) / pPPriv->vw; 1082c35d236eSmrg pPPriv->dT = (pPPriv->dh << 20) / pPPriv->vh; 1083c35d236eSmrg 1084c35d236eSmrg for (pCookie = pPPriv->pCookies; nBox--; pBox++) { 1085c35d236eSmrg int n1, n2; 1086c35d236eSmrg 1087c35d236eSmrg if (pRegion) { 1088c35d236eSmrg n1 = ((pBox->x1 - pPPriv->dx) * pPPriv->vw + dw1) / pPPriv->dw; 1089c35d236eSmrg n2 = ((pBox->x2 - pPPriv->dx) * pPPriv->vw - 1) / pPPriv->dw; 1090c35d236eSmrg 1091c35d236eSmrg if (n1 > n2) 1092c35d236eSmrg continue; /* Clip is subpixel */ 1093c35d236eSmrg 1094c35d236eSmrg pCookie->xy = n1 + pPPriv->vx; 1095c35d236eSmrg pCookie->wh = n2 - n1 + 1; 1096c35d236eSmrg pCookie->s = n1 * pPPriv->dS + (pPPriv->dx << 20); 1097c35d236eSmrg pCookie->y1 = pBox->y1; 1098c35d236eSmrg pCookie->y2 = pBox->y2; 1099c35d236eSmrg } 1100c35d236eSmrg 1101c35d236eSmrg n1 = ((pCookie->y1 - pPPriv->dy) * pPPriv->vh + dh1) / pPPriv->dh; 1102c35d236eSmrg n2 = ((pCookie->y2 - pPPriv->dy) * pPPriv->vh - 1) / pPPriv->dh; 1103c35d236eSmrg pCookie->xy = (pCookie->xy & 0xFFFF) | ((n1 + pPPriv->vy) << 16); 1104c35d236eSmrg pCookie->wh = (pCookie->wh & 0xFFFF) | ((n2 - n1 + 1) << 16); 1105c35d236eSmrg pCookie->t = n1 * pPPriv->dT + (pPPriv->dy << 20); 1106c35d236eSmrg if (n1 > n2) pCookie->t = -1; 1107c35d236eSmrg 1108c35d236eSmrg pCookie++; 1109c35d236eSmrg } 1110c35d236eSmrg 1111c35d236eSmrg pPPriv->nCookies = pCookie - pPPriv->pCookies; 1112c35d236eSmrg return TRUE; 1113c35d236eSmrg} 1114c35d236eSmrg 1115c35d236eSmrgstatic void 1116c35d236eSmrgGetYUV(PortPrivPtr pPPriv) 1117c35d236eSmrg{ 1118c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1119c35d236eSmrg ScrnInfoPtr pScrn = pAPriv->pScrn; 1120c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 1121c35d236eSmrg CookiePtr pCookie = pPPriv->pCookies; 1122c35d236eSmrg int nCookies = pPPriv->nCookies; 1123c35d236eSmrg 1124c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "GetYUV\n")); 1125c35d236eSmrg 1126c35d236eSmrg if (!nCookies || (GLINT_READ_REG(InFIFOSpace) < 200)) 1127c35d236eSmrg return; 1128c35d236eSmrg 1129c35d236eSmrg GLINT_WAIT(25); 1130c35d236eSmrg CHECKCLIPPING; 1131c35d236eSmrg 1132c35d236eSmrg GLINT_WRITE_REG(1 << 16, dY); 1133c35d236eSmrg GLINT_WRITE_REG(0, RasterizerMode); 1134c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode); 1135c35d236eSmrg GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode); 1136c35d236eSmrg GLINT_WRITE_REG(pPPriv->dS, dSdx); 1137c35d236eSmrg GLINT_WRITE_REG(0, dSdyDom); 1138c35d236eSmrg GLINT_WRITE_REG(0, dTdx); 1139c35d236eSmrg GLINT_WRITE_REG(pPPriv->dT, dTdyDom); 1140c35d236eSmrg GLINT_WRITE_REG(0, PMTextureBaseAddress); 1141c35d236eSmrg GLINT_WRITE_REG(pAPriv->dTextureDataFormat, PMTextureDataFormat); 1142c35d236eSmrg GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */ 1143c35d236eSmrg (11 << 13) | (11 << 9) | /* TextureSize log2 */ 1144c35d236eSmrg UNIT_ENABLE, PMTextureReadMode); 1145c35d236eSmrg if (pScrn->depth == 8) 1146c35d236eSmrg GLINT_WRITE_REG(UNIT_ENABLE, TexelLUTMode); 1147c35d236eSmrg GLINT_WRITE_REG((0 << 4) /* RGB */ | 1148c35d236eSmrg (3 << 1) /* Copy */ | 1149c35d236eSmrg UNIT_ENABLE, TextureColorMode); 1150c35d236eSmrg GLINT_WRITE_REG((1 << 10) | /* RGB */ 1151c35d236eSmrg ((16 & 0x10) << 12) | 1152c35d236eSmrg ((16 & 0x0F) << 2) | /* 5:6:5f */ 1153c35d236eSmrg UNIT_ENABLE, DitherMode); 1154c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); 1155c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferPProd, FBReadMode); 1156c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferBase[0] >> 1 /* 16 */, FBWindowBase); 1157c35d236eSmrg GLINT_WRITE_REG(0x1, FBReadPixel); /* 16 */ 1158c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, YUVMode); 1159c35d236eSmrg 1160c35d236eSmrg for (; nCookies--; pCookie++) 1161c35d236eSmrg if (pCookie->t >= 0) { 1162c35d236eSmrg GLINT_WAIT(5); 1163c35d236eSmrg GLINT_WRITE_REG(pCookie->xy, RectangleOrigin); 1164c35d236eSmrg GLINT_WRITE_REG(pCookie->wh, RectangleSize); 1165c35d236eSmrg GLINT_WRITE_REG(pCookie->s, SStart); 1166c35d236eSmrg GLINT_WRITE_REG(pCookie->t, TStart); 1167c35d236eSmrg GLINT_WRITE_REG(PrimitiveRectangle | 1168c35d236eSmrg XPositive | 1169c35d236eSmrg YPositive | 1170c35d236eSmrg TextureEnable, Render); 1171c35d236eSmrg } 1172c35d236eSmrg 1173c35d236eSmrg pGlint->x = pGlint->y = -1; /* Force reload */ 1174c35d236eSmrg pGlint->w = pGlint->h = -1; 1175c35d236eSmrg pGlint->ROP = 0xFF; 1176c35d236eSmrg 1177c35d236eSmrg GLINT_WAIT(9); 1178c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); 1179c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode); 1180c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); 1181c35d236eSmrg if (pScrn->depth == 8) 1182c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, TexelLUTMode); 1183c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); 1184c35d236eSmrg GLINT_WRITE_REG(pGlint->pprod, FBReadMode); 1185c35d236eSmrg GLINT_WRITE_REG(0, FBWindowBase); 1186c35d236eSmrg GLINT_WRITE_REG(pGlint->PixelWidth, FBReadPixel); 1187c35d236eSmrg GLINT_WRITE_REG(UNIT_DISABLE, YUVMode); 1188c35d236eSmrg} 1189c35d236eSmrg 1190c35d236eSmrgstatic int 1191c35d236eSmrgSetBkgCol(PortPrivPtr pPPriv, int value) 1192c35d236eSmrg{ 1193c35d236eSmrg pPPriv->Attribute[6] = value; 1194c35d236eSmrg 1195c35d236eSmrg pPPriv->BkgCol = ((value & 0xF80000) >> 8) | 1196c35d236eSmrg ((value & 0x00FC00) >> 5) | 1197c35d236eSmrg ((value & 0x0000F8) >> 3); 1198c35d236eSmrg 1199c35d236eSmrg pPPriv->BkgCol += pPPriv->BkgCol << 16; 1200c35d236eSmrg 1201c35d236eSmrg if (pPPriv->VideoOn) { 1202c35d236eSmrg BlackOut(pPPriv, NULL); 1203c35d236eSmrg GetYUV(pPPriv); 1204c35d236eSmrg } 1205c35d236eSmrg 1206c35d236eSmrg return Success; 1207c35d236eSmrg} 1208c35d236eSmrg 1209c35d236eSmrg/* os/WaitFor.c */ 1210c35d236eSmrg 1211c35d236eSmrgstatic CARD32 1212c35d236eSmrgTimerCallback(OsTimerPtr pTim, CARD32 now, pointer p) 1213c35d236eSmrg{ 1214c35d236eSmrg AdaptorPrivPtr pAPriv = (AdaptorPrivPtr) p; 1215c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); 1216c35d236eSmrg PortPrivPtr pPPriv; 1217c35d236eSmrg int i, delay; 1218c35d236eSmrg 1219c35d236eSmrg if (!pAPriv->pm2p) { 1220c35d236eSmrg pPPriv = &pAPriv->Port[0]; 1221c35d236eSmrg 1222c35d236eSmrg if (pPPriv->VideoOn > VIDEO_OFF) { 1223c35d236eSmrg pPPriv->FrameAcc += pPPriv->FramesPerSec; 1224c35d236eSmrg 1225c35d236eSmrg if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { 1226c35d236eSmrg pPPriv->FrameAcc -= pAPriv->FramesPerSec; 1227c35d236eSmrg 1228c35d236eSmrg PutYUV(pPPriv, (!pPPriv->pFBArea[1]) ? 1229c35d236eSmrg pPPriv->BufferBase[0] : pPPriv->BufferBase[1 - 1230c35d236eSmrg GLINT_READ_REG(VSABase + VSVideoAddressIndex)], FORMAT_YUYV, 1, 0); 1231c35d236eSmrg } 1232c35d236eSmrg } else 1233c35d236eSmrg if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { 1234c35d236eSmrg StopVideoStream(pPPriv, TRUE); 1235c35d236eSmrg RestoreVideoStd(pAPriv); 1236c35d236eSmrg } 1237c35d236eSmrg 1238c35d236eSmrg pPPriv = &pAPriv->Port[1]; 1239c35d236eSmrg 1240c35d236eSmrg if (pPPriv->VideoOn > VIDEO_OFF) { 1241c35d236eSmrg pPPriv->FrameAcc += pPPriv->FramesPerSec; 1242c35d236eSmrg 1243c35d236eSmrg if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { 1244c35d236eSmrg pPPriv->FrameAcc -= pAPriv->FramesPerSec; 1245c35d236eSmrg 1246c35d236eSmrg GetYUV(pPPriv); 1247c35d236eSmrg } 1248c35d236eSmrg } else 1249c35d236eSmrg if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { 1250c35d236eSmrg StopVideoStream(pPPriv, TRUE); 1251c35d236eSmrg RestoreVideoStd(pAPriv); 1252c35d236eSmrg } 1253c35d236eSmrg } 1254c35d236eSmrg 1255c35d236eSmrg for (i = 2; i <= 5; i++) { 1256c35d236eSmrg if (pAPriv->Port[i].StopDelay >= 0) { 1257c35d236eSmrg if (!(pAPriv->Port[i].StopDelay--)) { 1258c35d236eSmrg FreeBuffers(&pAPriv->Port[i]); 1259c35d236eSmrg FreeCookies(&pAPriv->Port[i]); 1260c35d236eSmrg pAPriv->TimerUsers &= ~(1 << i); 1261c35d236eSmrg } 1262c35d236eSmrg } 1263c35d236eSmrg } 1264c35d236eSmrg 1265c35d236eSmrg if (!pAPriv->pm2p) { 1266c35d236eSmrg if (pAPriv->Port[0].StreamOn) { 1267c35d236eSmrg delay = GLINT_READ_REG(VSABase + VSCurrentLine); 1268c35d236eSmrg 1269c35d236eSmrg if (!(GLINT_READ_REG(VSStatus) & VS_FieldOne0A)) 1270c35d236eSmrg delay += pAPriv->FrameLines >> 1; 1271c35d236eSmrg 1272c35d236eSmrg if (delay > (pAPriv->IntLine - 16)) 1273c35d236eSmrg delay -= pAPriv->FrameLines; 1274c35d236eSmrg 1275c35d236eSmrg return (((pAPriv->IntLine - delay) * pAPriv->LinePer) + 999999) / 1000000; 1276c35d236eSmrg } else if (pAPriv->Port[1].StreamOn) { 1277c35d236eSmrg delay = GLINT_READ_REG(VSBBase + VSCurrentLine); 1278c35d236eSmrg 1279c35d236eSmrg if (!(GLINT_READ_REG(VSStatus) & VS_FieldOne0B)) 1280c35d236eSmrg delay += pAPriv->FrameLines >> 1; 1281c35d236eSmrg 1282c35d236eSmrg if (delay > (pAPriv->IntLine - 16)) 1283c35d236eSmrg delay -= pAPriv->FrameLines; 1284c35d236eSmrg 1285c35d236eSmrg return (((pAPriv->IntLine - delay) * pAPriv->LinePer) + 999999) / 1000000; 1286c35d236eSmrg } 1287c35d236eSmrg } 1288c35d236eSmrg 1289c35d236eSmrg if (pAPriv->TimerUsers) 1290c35d236eSmrg return pAPriv->Instant; 1291c35d236eSmrg 1292c35d236eSmrg return 0; /* Cancel */ 1293c35d236eSmrg} 1294c35d236eSmrg 1295c35d236eSmrg 1296c35d236eSmrg/* 1297c35d236eSmrg * Video stream (bounce buffer <-> hardware) 1298c35d236eSmrg */ 1299c35d236eSmrg 1300c35d236eSmrgstatic void 1301c35d236eSmrgStopVideoStream(PortPrivPtr pPPriv, Bool shutdown) 1302c35d236eSmrg{ 1303c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1304c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); 1305c35d236eSmrg int VideoOn; 1306c35d236eSmrg 1307c35d236eSmrg pPPriv->StopDelay = -1; 1308c35d236eSmrg 1309c35d236eSmrg VideoOn = pPPriv->VideoOn; 1310c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 1311c35d236eSmrg 1312c35d236eSmrg if (!pPPriv->StreamOn) 1313c35d236eSmrg return; 1314c35d236eSmrg 1315c35d236eSmrg if (pAPriv->pm2p) { 1316c35d236eSmrg xvipcHandshake(pPPriv, OP_STOP, TRUE); 1317c35d236eSmrg 1318c35d236eSmrg pPPriv->StreamOn = FALSE; 1319c35d236eSmrg 1320c35d236eSmrg if (shutdown) 1321c35d236eSmrg FreeCookies(pPPriv); 1322c35d236eSmrg 1323c35d236eSmrg if (VideoOn > VIDEO_OFF && pGlint->NoAccel) 1324c35d236eSmrg Permedia2Sync(pAPriv->pScrn); 1325c35d236eSmrg 1326c35d236eSmrg return; 1327c35d236eSmrg } 1328c35d236eSmrg 1329c35d236eSmrg if (pPPriv == &pAPriv->Port[0]) { 1330c35d236eSmrg int line, eeek = 0; 1331c35d236eSmrg 1332c35d236eSmrg do { 1333c35d236eSmrg if (eeek++ > 1000000) break; 1334c35d236eSmrg line = GLINT_READ_REG(VSABase + VSCurrentLine); 1335c35d236eSmrg } while (line > 15); 1336c35d236eSmrg 1337c35d236eSmrg GLINT_WRITE_REG(0, VSABase + VSControl); 1338c35d236eSmrg 1339c35d236eSmrg pAPriv->Port[0].StreamOn = FALSE; 1340c35d236eSmrg 1341c35d236eSmrg usleep(80000); 1342c35d236eSmrg } else { 1343c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, 0x83); 1344c35d236eSmrg if (!ColorBars) 1345c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2); 1346c35d236eSmrg 1347c35d236eSmrg GLINT_WRITE_REG(0, VSBBase + VSControl); 1348c35d236eSmrg 1349c35d236eSmrg pAPriv->Port[1].StreamOn = FALSE; 1350c35d236eSmrg } 1351c35d236eSmrg 1352c35d236eSmrg if (!pAPriv->Port[0].StreamOn && !pAPriv->Port[1].StreamOn) { 1353c35d236eSmrg if (shutdown) 1354c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2); 1355c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x00); 1356c35d236eSmrg } 1357c35d236eSmrg 1358c35d236eSmrg if (shutdown) { 1359c35d236eSmrg FreeBuffers(pPPriv); 1360c35d236eSmrg FreeCookies(pPPriv); 1361c35d236eSmrg 1362c35d236eSmrg if (pAPriv->TimerUsers) { 1363c35d236eSmrg pAPriv->TimerUsers &= ~PORTNUM(pPPriv); 1364c35d236eSmrg if (!pAPriv->TimerUsers) 1365c35d236eSmrg TimerCancel(pAPriv->Timer); 1366c35d236eSmrg } 1367c35d236eSmrg 1368c35d236eSmrg if (VideoOn > VIDEO_OFF && pGlint->NoAccel) 1369c35d236eSmrg Permedia2Sync(pAPriv->pScrn); 1370c35d236eSmrg } 1371c35d236eSmrg} 1372c35d236eSmrg 1373c35d236eSmrgstatic Bool 1374c35d236eSmrgStartVideoStream(PortPrivPtr pPPriv, RegionPtr pRegion) 1375c35d236eSmrg{ 1376c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1377c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); 1378c35d236eSmrg 1379c35d236eSmrg if (pAPriv->VideoStd < 0) 1380c35d236eSmrg return FALSE; 1381c35d236eSmrg 1382c35d236eSmrg pPPriv->StopDelay = -1; 1383c35d236eSmrg 1384c35d236eSmrg if (pAPriv->pm2p) { 1385c35d236eSmrg if (pPPriv == &pAPriv->Port[0]) { 1386c35d236eSmrg if (!RemakePutCookies(pPPriv, pRegion)) 1387c35d236eSmrg return FALSE; 1388c35d236eSmrg if (pPPriv->StreamOn) 1389c35d236eSmrg return TRUE; 1390c35d236eSmrg } else { 1391c35d236eSmrg if (!RemakeGetCookies(pPPriv, pRegion)) 1392c35d236eSmrg return FALSE; 1393c35d236eSmrg if (pPPriv->StreamOn) { 1394c35d236eSmrg BlackOut(pPPriv, pRegion); 1395c35d236eSmrg return TRUE; 1396c35d236eSmrg } 1397c35d236eSmrg } 1398c35d236eSmrg 1399c35d236eSmrg xvipc.a = pPPriv->BuffersRequested; 1400c35d236eSmrg xvipc.b = !pPPriv->Attribute[4]; 1401c35d236eSmrg xvipc.c = 1 + (pPPriv->Attribute[4] & 2); 1402c35d236eSmrg 1403c35d236eSmrg if (!xvipcHandshake(pPPriv, OP_START, TRUE)) 1404c35d236eSmrg return FALSE; 1405c35d236eSmrg 1406c35d236eSmrg if (pPPriv == &pAPriv->Port[1]) { 1407c35d236eSmrg pPPriv->BufferBase[0] = xvipc.d; 1408c35d236eSmrg BlackOut(pPPriv, pRegion); 1409c35d236eSmrg } 1410c35d236eSmrg 1411c35d236eSmrg return pPPriv->StreamOn = TRUE; 1412c35d236eSmrg } else { 1413c35d236eSmrg CARD32 Base = (pPPriv == &pAPriv->Port[0]) ? VSABase : VSBBase; 1414c35d236eSmrg 1415c35d236eSmrg if (pPPriv->BuffersAllocated < pPPriv->BuffersRequested) { 1416c35d236eSmrg int height = ((pAPriv->VideoStd == NTSC) ? 512 : 608) >> (!pPPriv->Attribute[4]); 1417c35d236eSmrg 1418c35d236eSmrg if (!AllocateBuffers(pPPriv, 704, height, 2, pPPriv->BuffersRequested, 0)) 1419c35d236eSmrg return FALSE; 1420c35d236eSmrg 1421c35d236eSmrg pPPriv->fw = 704; 1422c35d236eSmrg pPPriv->fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >> 1423c35d236eSmrg (!pPPriv->Attribute[4]); 1424c35d236eSmrg } 1425c35d236eSmrg 1426c35d236eSmrg if (pPPriv == &pAPriv->Port[0]) { 1427c35d236eSmrg if (!RemakePutCookies(pPPriv, pRegion)) 1428c35d236eSmrg return FALSE; 1429c35d236eSmrg } else { 1430c35d236eSmrg if (!RemakeGetCookies(pPPriv, pRegion)) 1431c35d236eSmrg return FALSE; 1432c35d236eSmrg 1433c35d236eSmrg BlackOut(pPPriv, pRegion); 1434c35d236eSmrg } 1435c35d236eSmrg 1436c35d236eSmrg if (pPPriv->StreamOn) 1437c35d236eSmrg return TRUE; 1438c35d236eSmrg 1439c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferBase[0] / 8, Base + VSVideoAddress0); 1440c35d236eSmrg if (pPPriv->pFBArea[1]) 1441c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferBase[1] / 8, Base + VSVideoAddress1); 1442c35d236eSmrg else 1443c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferBase[0] / 8, Base + VSVideoAddress1); 1444c35d236eSmrg GLINT_WRITE_REG(pPPriv->BufferStride / 8, Base + VSVideoStride); 1445c35d236eSmrg 1446c35d236eSmrg GLINT_WRITE_REG(0, Base + VSCurrentLine); 1447c35d236eSmrg 1448c35d236eSmrg if (pAPriv->VideoStd == NTSC) { 1449c35d236eSmrg GLINT_WRITE_REG(16, Base + VSVideoStartLine); 1450c35d236eSmrg GLINT_WRITE_REG(16 + 240, Base + VSVideoEndLine); 1451c35d236eSmrg GLINT_WRITE_REG(288 + (8 & ~3) * 2, Base + VSVideoStartData); 1452c35d236eSmrg GLINT_WRITE_REG(288 + ((8 & ~3) + 704) * 2, Base + VSVideoEndData); 1453c35d236eSmrg } else { 1454c35d236eSmrg GLINT_WRITE_REG(16, Base + VSVideoStartLine); 1455c35d236eSmrg GLINT_WRITE_REG(16 + 288, Base + VSVideoEndLine); 1456c35d236eSmrg GLINT_WRITE_REG(288 + (8 & ~3) * 2, Base + VSVideoStartData); 1457c35d236eSmrg GLINT_WRITE_REG(288 + ((8 & ~3) + 704) * 2, Base + VSVideoEndData); 1458c35d236eSmrg } 1459c35d236eSmrg 1460c35d236eSmrg GLINT_WRITE_REG(2, Base + VSVideoAddressHost); 1461c35d236eSmrg GLINT_WRITE_REG(0, Base + VSVideoAddressIndex); 1462c35d236eSmrg 1463c35d236eSmrg if (pPPriv == &pAPriv->Port[0]) { 1464c35d236eSmrg int line, eeek = 0; 1465c35d236eSmrg 1466c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x0D); 1467c35d236eSmrg 1468c35d236eSmrg do { 1469c35d236eSmrg if (eeek++ > 1000000) break; 1470c35d236eSmrg line = GLINT_READ_REG(VSABase + VSCurrentLine); 1471c35d236eSmrg } while (line > 15); 1472c35d236eSmrg 1473c35d236eSmrg GLINT_WRITE_REG(VSA_Video | 1474c35d236eSmrg (pPPriv->Attribute[4] ? 1475c35d236eSmrg VSA_CombineFields : VSA_Discard_FieldTwo), 1476c35d236eSmrg VSABase + VSControl); 1477c35d236eSmrg if (ColorBars) 1478c35d236eSmrg if (!pAPriv->Port[1].StreamOn) { 1479c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, 0x83); 1480c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, Enc61[pAPriv->VideoStd]); 1481c35d236eSmrg } 1482c35d236eSmrg } else { 1483c35d236eSmrg GLINT_WRITE_REG(VSB_Video | 1484c35d236eSmrg (pPPriv->Attribute[4] ? VSB_CombineFields : 0) | 1485c35d236eSmrg /* VSB_GammaCorrect | */ 1486c35d236eSmrg (16 << 4) | /* 5:6:5 */ 1487c35d236eSmrg (1 << 9) | /* 16 */ 1488c35d236eSmrg VSB_RGBOrder, VSBBase + VSControl); 1489c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x0D); 1490c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, Enc3A[pPPriv->Plug]); 1491c35d236eSmrg xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, Enc61[pAPriv->VideoStd]); 1492c35d236eSmrg } 1493c35d236eSmrg 1494c35d236eSmrg pAPriv->TimerUsers |= 1 << PORTNUM(pPPriv); 1495c35d236eSmrg TimerSet(pAPriv->Timer, 0, 80, TimerCallback, pAPriv); 1496c35d236eSmrg 1497c35d236eSmrg return pPPriv->StreamOn = TRUE; 1498c35d236eSmrg } 1499c35d236eSmrg 1500c35d236eSmrg return FALSE; 1501c35d236eSmrg} 1502c35d236eSmrg 1503c35d236eSmrg 1504c35d236eSmrg/* 1505c35d236eSmrg * Xv interface 1506c35d236eSmrg */ 1507c35d236eSmrg 1508c35d236eSmrgstatic int 1509c35d236eSmrgPermedia2PutVideo(ScrnInfoPtr pScrn, 1510c35d236eSmrg short vid_x, short vid_y, short drw_x, short drw_y, 1511c35d236eSmrg short vid_w, short vid_h, short drw_w, short drw_h, 1512c35d236eSmrg RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) 1513c35d236eSmrg{ 1514c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 1515c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1516c35d236eSmrg int sw, sh; 1517c35d236eSmrg 1518c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 1519c35d236eSmrg "PutVideo %d,%d,%d,%d -> %d,%d,%d,%d\n", 1520c35d236eSmrg vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); 1521c35d236eSmrg 1522c35d236eSmrg sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; 1523c35d236eSmrg sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; 1524c35d236eSmrg 1525c35d236eSmrg if ((vid_x + vid_w) > sw || 1526c35d236eSmrg (vid_y + vid_h) > sh) 1527c35d236eSmrg return BadValue; 1528c35d236eSmrg 1529c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 1530c35d236eSmrg 1531c35d236eSmrg pPPriv->vx = ((vid_x << 10) * pPPriv->fw) / sw; 1532c35d236eSmrg pPPriv->vy = ((vid_y << 10) * pPPriv->fh) / sh; 1533c35d236eSmrg pPPriv->vw = ((vid_w << 10) * pPPriv->fw) / sw; 1534c35d236eSmrg pPPriv->vh = ((vid_h << 10) * pPPriv->fh) / sh; 1535c35d236eSmrg 1536c35d236eSmrg pPPriv->dx = drw_x; 1537c35d236eSmrg pPPriv->dy = drw_y; 1538c35d236eSmrg pPPriv->dw = drw_w; 1539c35d236eSmrg pPPriv->dh = drw_h; 1540c35d236eSmrg 1541c35d236eSmrg pPPriv->FrameAcc = pAPriv->FramesPerSec; 1542c35d236eSmrg 1543c35d236eSmrg if (!StartVideoStream(pPPriv, clipBoxes)) 1544c35d236eSmrg return XvBadAlloc; 1545c35d236eSmrg 1546c35d236eSmrg pPPriv->VideoOn = VIDEO_ON; 1547c35d236eSmrg 1548c35d236eSmrg return Success; 1549c35d236eSmrg} 1550c35d236eSmrg 1551c35d236eSmrgstatic int 1552c35d236eSmrgPermedia2PutStill(ScrnInfoPtr pScrn, 1553c35d236eSmrg short vid_x, short vid_y, short drw_x, short drw_y, 1554c35d236eSmrg short vid_w, short vid_h, short drw_w, short drw_h, 1555c35d236eSmrg RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) 1556c35d236eSmrg{ 1557c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 1558c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1559c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 1560c35d236eSmrg int sw, sh, r = Success; 1561c35d236eSmrg 1562c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 1563c35d236eSmrg "PutStill %d,%d,%d,%d -> %d,%d,%d,%d\n", 1564c35d236eSmrg vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); 1565c35d236eSmrg 1566c35d236eSmrg sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; 1567c35d236eSmrg sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; 1568c35d236eSmrg 1569c35d236eSmrg if ((vid_x + vid_w) > sw || 1570c35d236eSmrg (vid_y + vid_h) > sh) 1571c35d236eSmrg return BadValue; 1572c35d236eSmrg 1573c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 1574c35d236eSmrg 1575c35d236eSmrg pPPriv->vx = ((vid_x << 10) * pPPriv->fw) / sw; 1576c35d236eSmrg pPPriv->vy = ((vid_y << 10) * pPPriv->fh) / sh; 1577c35d236eSmrg pPPriv->vw = ((vid_w << 10) * pPPriv->fw) / sw; 1578c35d236eSmrg pPPriv->vh = ((vid_h << 10) * pPPriv->fh) / sh; 1579c35d236eSmrg 1580c35d236eSmrg pPPriv->dx = drw_x; 1581c35d236eSmrg pPPriv->dy = drw_y; 1582c35d236eSmrg pPPriv->dw = drw_w; 1583c35d236eSmrg pPPriv->dh = drw_h; 1584c35d236eSmrg 1585c35d236eSmrg pPPriv->FrameAcc = pAPriv->FramesPerSec; 1586c35d236eSmrg 1587c35d236eSmrg if (!StartVideoStream(pPPriv, clipBoxes)) 1588c35d236eSmrg return XvBadAlloc; 1589c35d236eSmrg 1590c35d236eSmrg if (pAPriv->pm2p) { 1591c35d236eSmrg /* Sleep, not busy wait, until the very next frame is ready. 1592c35d236eSmrg Accept memory requests and other window's update events 1593c35d236eSmrg in the meantime. */ 1594c35d236eSmrg for (pPPriv->VideoOn = VIDEO_ONE_SHOT; pPPriv->VideoOn;) 1595c35d236eSmrg if (!xvipcHandshake(pPPriv, OP_UPDATE, TRUE)) { 1596c35d236eSmrg r = FALSE; 1597c35d236eSmrg break; 1598c35d236eSmrg } 1599c35d236eSmrg } else { 1600c35d236eSmrg usleep(80000); 1601c35d236eSmrg 1602c35d236eSmrg PutYUV(pPPriv, (!pPPriv->pFBArea[1]) ? 1603c35d236eSmrg pPPriv->BufferBase[0] : pPPriv->BufferBase[1 - 1604c35d236eSmrg GLINT_READ_REG(VSABase + VSVideoAddressIndex)], FORMAT_YUYV, 1, 0); 1605c35d236eSmrg } 1606c35d236eSmrg 1607c35d236eSmrg pPPriv->StopDelay = 125; 1608c35d236eSmrg 1609c35d236eSmrg return r; 1610c35d236eSmrg} 1611c35d236eSmrg 1612c35d236eSmrgstatic int 1613c35d236eSmrgPermedia2GetVideo(ScrnInfoPtr pScrn, 1614c35d236eSmrg short vid_x, short vid_y, short drw_x, short drw_y, 1615c35d236eSmrg short vid_w, short vid_h, short drw_w, short drw_h, 1616c35d236eSmrg RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) 1617c35d236eSmrg{ 1618c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 1619c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1620c35d236eSmrg int sw, sh; 1621c35d236eSmrg 1622c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 1623c35d236eSmrg "GetVideo %d,%d,%d,%d <- %d,%d,%d,%d\n", 1624c35d236eSmrg vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); 1625c35d236eSmrg 1626c35d236eSmrg sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; 1627c35d236eSmrg sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; 1628c35d236eSmrg 1629c35d236eSmrg if ((vid_x + vid_w) > sw || 1630c35d236eSmrg (vid_y + vid_h) > sh) { 1631c35d236eSmrg return BadValue; 1632c35d236eSmrg } 1633c35d236eSmrg 1634c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 1635c35d236eSmrg 1636c35d236eSmrg pPPriv->vx = (vid_x * pPPriv->fw) / sw; 1637c35d236eSmrg pPPriv->vy = (vid_y * pPPriv->fh) / sh; 1638c35d236eSmrg pPPriv->vw = (vid_w * pPPriv->fw) / sw; 1639c35d236eSmrg pPPriv->vh = (vid_h * pPPriv->fh) / sh; 1640c35d236eSmrg 1641c35d236eSmrg pPPriv->dx = drw_x; 1642c35d236eSmrg pPPriv->dy = drw_y; 1643c35d236eSmrg pPPriv->dw = drw_w; 1644c35d236eSmrg pPPriv->dh = drw_h; 1645c35d236eSmrg 1646c35d236eSmrg pPPriv->FrameAcc = pAPriv->FramesPerSec; 1647c35d236eSmrg 1648c35d236eSmrg if (!StartVideoStream(pPPriv, clipBoxes)) { 1649c35d236eSmrg return XvBadAlloc; 1650c35d236eSmrg } 1651c35d236eSmrg 1652c35d236eSmrg GetYUV(pPPriv); 1653c35d236eSmrg 1654c35d236eSmrg pPPriv->VideoOn = VIDEO_ON; 1655c35d236eSmrg 1656c35d236eSmrg return Success; 1657c35d236eSmrg} 1658c35d236eSmrg 1659c35d236eSmrgstatic int 1660c35d236eSmrgPermedia2GetStill(ScrnInfoPtr pScrn, 1661c35d236eSmrg short vid_x, short vid_y, short drw_x, short drw_y, 1662c35d236eSmrg short vid_w, short vid_h, short drw_w, short drw_h, 1663c35d236eSmrg RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) 1664c35d236eSmrg{ 1665c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 1666c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1667c35d236eSmrg int sw, sh; 1668c35d236eSmrg 1669c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 1670c35d236eSmrg "GetStill %d,%d,%d,%d <- %d,%d,%d,%d\n", 1671c35d236eSmrg vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); 1672c35d236eSmrg 1673c35d236eSmrg sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; 1674c35d236eSmrg sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; 1675c35d236eSmrg 1676c35d236eSmrg if ((vid_x + vid_w) > sw || 1677c35d236eSmrg (vid_y + vid_h) > sh) 1678c35d236eSmrg return BadValue; 1679c35d236eSmrg 1680c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 1681c35d236eSmrg 1682c35d236eSmrg pPPriv->vx = (vid_x * pPPriv->fw) / sw; 1683c35d236eSmrg pPPriv->vy = (vid_y * pPPriv->fh) / sh; 1684c35d236eSmrg pPPriv->vw = (vid_w * pPPriv->fw) / sw; 1685c35d236eSmrg pPPriv->vh = (vid_h * pPPriv->fh) / sh; 1686c35d236eSmrg 1687c35d236eSmrg pPPriv->dx = drw_x; 1688c35d236eSmrg pPPriv->dy = drw_y; 1689c35d236eSmrg pPPriv->dw = drw_w; 1690c35d236eSmrg pPPriv->dh = drw_h; 1691c35d236eSmrg 1692c35d236eSmrg pPPriv->FrameAcc = pAPriv->FramesPerSec; 1693c35d236eSmrg 1694c35d236eSmrg if (!StartVideoStream(pPPriv, clipBoxes)) 1695c35d236eSmrg return XvBadAlloc; 1696c35d236eSmrg 1697c35d236eSmrg GetYUV(pPPriv); 1698c35d236eSmrg 1699c35d236eSmrg return Success; 1700c35d236eSmrg} 1701c35d236eSmrg 1702c35d236eSmrgstatic void 1703c35d236eSmrgCopyYV12LE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch) 1704c35d236eSmrg{ 1705c35d236eSmrg int Y_size = width * height; 1706c35d236eSmrg CARD8 *V = Y + Y_size; 1707c35d236eSmrg CARD8 *U = V + (Y_size >> 2); 1708c35d236eSmrg int pad = (pitch >> 2) - (width >> 1); 1709c35d236eSmrg int x; 1710c35d236eSmrg 1711c35d236eSmrg width >>= 1; 1712c35d236eSmrg 1713c35d236eSmrg for (height >>= 1; height > 0; height--) { 1714c35d236eSmrg for (x = 0; x < width; Y += 2, x++) 1715c35d236eSmrg *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); 1716c35d236eSmrg dst += pad; 1717c35d236eSmrg for (x = 0; x < width; Y += 2, x++) 1718c35d236eSmrg *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); 1719c35d236eSmrg dst += pad; 1720c35d236eSmrg U += width; 1721c35d236eSmrg V += width; 1722c35d236eSmrg } 1723c35d236eSmrg} 1724c35d236eSmrg 1725c35d236eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 1726c35d236eSmrg 1727c35d236eSmrgstatic void 1728c35d236eSmrgCopyYV12BE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch) 1729c35d236eSmrg{ 1730c35d236eSmrg int Y_size = width * height; 1731c35d236eSmrg CARD8 *V = Y + Y_size; 1732c35d236eSmrg CARD8 *U = V + (Y_size >> 2); 1733c35d236eSmrg int pad = (pitch >> 2) - (width >> 1); 1734c35d236eSmrg int x; 1735c35d236eSmrg 1736c35d236eSmrg width >>= 1; 1737c35d236eSmrg 1738c35d236eSmrg for (height >>= 1; height > 0; height--) { 1739c35d236eSmrg for (x = 0; x < width; Y += 2, x++) 1740c35d236eSmrg *dst++ = V[x] + (Y[1] << 8) + (U[x] << 16) + (Y[0] << 24); 1741c35d236eSmrg dst += pad; 1742c35d236eSmrg for (x = 0; x < width; Y += 2, x++) 1743c35d236eSmrg *dst++ = V[x] + (Y[1] << 8) + (U[x] << 16) + (Y[0] << 24); 1744c35d236eSmrg dst += pad; 1745c35d236eSmrg U += width; 1746c35d236eSmrg V += width; 1747c35d236eSmrg } 1748c35d236eSmrg} 1749c35d236eSmrg 1750c35d236eSmrg#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ 1751c35d236eSmrg 1752c35d236eSmrgstatic void 1753c35d236eSmrgCopyFlat(CARD8 *src, CARD8 *dst, int width, int height, int pitch) 1754c35d236eSmrg{ 1755c35d236eSmrg if (width == pitch) { 1756c35d236eSmrg memcpy(dst, src, width * height); 1757c35d236eSmrg return; 1758c35d236eSmrg } 1759c35d236eSmrg 1760c35d236eSmrg while (height > 0) { 1761c35d236eSmrg memcpy(dst, src, width); 1762c35d236eSmrg dst += pitch; 1763c35d236eSmrg src += width; 1764c35d236eSmrg height--; 1765c35d236eSmrg } 1766c35d236eSmrg} 1767c35d236eSmrg 1768c35d236eSmrgstatic int 1769c35d236eSmrgPermedia2PutImage(ScrnInfoPtr pScrn, 1770c35d236eSmrg short src_x, short src_y, short drw_x, short drw_y, 1771c35d236eSmrg short src_w, short src_h, short drw_w, short drw_h, 1772c35d236eSmrg int id, unsigned char *buf, short width, short height, 1773c35d236eSmrg Bool sync, RegionPtr clipBoxes, pointer data, 1774c35d236eSmrg DrawablePtr pDraw) 1775c35d236eSmrg{ 1776c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 1777c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1778c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 1779c35d236eSmrg int i; 1780c35d236eSmrg 1781c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 1782c35d236eSmrg "PutImage %d,%d,%d,%d -> %d,%d,%d,%d id=0x%08x buf=%p w=%d h=%d sync=%d\n", 1783c35d236eSmrg src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, 1784c35d236eSmrg id, buf, width, height, sync)); 1785c35d236eSmrg 1786c35d236eSmrg if ((src_x + src_w) > width || 1787c35d236eSmrg (src_y + src_h) > height) 1788c35d236eSmrg return BadValue; 1789c35d236eSmrg 1790c35d236eSmrg pPPriv->vx = src_x << 10; 1791c35d236eSmrg pPPriv->vy = src_y << 10; 1792c35d236eSmrg pPPriv->vw = src_w << 10; 1793c35d236eSmrg pPPriv->vh = src_h << 10; 1794c35d236eSmrg 1795c35d236eSmrg pPPriv->dx = drw_x; 1796c35d236eSmrg pPPriv->dy = drw_y; 1797c35d236eSmrg pPPriv->dw = drw_w; 1798c35d236eSmrg pPPriv->dh = drw_h; 1799c35d236eSmrg 1800c35d236eSmrg if (!RemakePutCookies(pPPriv, clipBoxes)) 1801c35d236eSmrg return XvBadAlloc; 1802c35d236eSmrg 1803c35d236eSmrg if (pPPriv->BuffersAllocated <= 0 || 1804c35d236eSmrg id != pPPriv->Id || /* same bpp */ 1805c35d236eSmrg width != pPPriv->fw || 1806c35d236eSmrg height != pPPriv->fh) 1807c35d236eSmrg { 1808c35d236eSmrg for (i = 0; i < ENTRIES(ScalerImages); i++) 1809c35d236eSmrg if (id == ScalerImages[i].id) 1810c35d236eSmrg break; 1811c35d236eSmrg 1812c35d236eSmrg if (i >= ENTRIES(ScalerImages)) 1813c35d236eSmrg return XvBadAlloc; 1814c35d236eSmrg#if 0 1815c35d236eSmrg if (pPPriv->BuffersAllocated <= 0 || 1816c35d236eSmrg pPPriv->Bpp != ScalerImages[i].bits_per_pixel || 1817c35d236eSmrg width > pPPriv->fw || height > pPPriv->fw || 1818c35d236eSmrg pPPriv->fw * pPPriv->fh > width * height * 2) 1819c35d236eSmrg#else 1820c35d236eSmrg if (1) 1821c35d236eSmrg#endif 1822c35d236eSmrg { 1823c35d236eSmrg Permedia2Sync(pScrn); 1824c35d236eSmrg 1825c35d236eSmrg if (!AllocateBuffers(pPPriv, width, height, 1826c35d236eSmrg (ScalerImages[i].bits_per_pixel + 7) >> 3, 1, 0)) { 1827c35d236eSmrg pPPriv->Id = 0; 1828c35d236eSmrg pPPriv->Bpp = 0; 1829c35d236eSmrg pPPriv->fw = 0; 1830c35d236eSmrg pPPriv->fh = 0; 1831c35d236eSmrg 1832c35d236eSmrg return XvBadAlloc; 1833c35d236eSmrg } 1834c35d236eSmrg 1835c35d236eSmrg pPPriv->Id = id; 1836c35d236eSmrg pPPriv->Bpp = ScalerImages[i].bits_per_pixel; 1837c35d236eSmrg pPPriv->fw = width; 1838c35d236eSmrg pPPriv->fh = height; 1839c35d236eSmrg 1840c35d236eSmrg RemoveableBuffers(pPPriv, TRUE); 1841c35d236eSmrg } else 1842c35d236eSmrg Permedia2Sync(pScrn); 1843c35d236eSmrg } else 1844c35d236eSmrg Permedia2Sync(pScrn); 1845c35d236eSmrg 1846c35d236eSmrg switch (id) { 1847c35d236eSmrg case LE4CC('Y','V','1','2'): 1848c35d236eSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 1849c35d236eSmrg CopyYV12LE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]), 1850c35d236eSmrg width, height, pPPriv->BufferStride); 1851c35d236eSmrg#else 1852c35d236eSmrg if (pGlint->FBDev) 1853c35d236eSmrg CopyYV12LE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]), 1854c35d236eSmrg width, height, pPPriv->BufferStride); 1855c35d236eSmrg else 1856c35d236eSmrg CopyYV12BE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]), 1857c35d236eSmrg width, height, pPPriv->BufferStride); 1858c35d236eSmrg#endif 1859c35d236eSmrg PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_YUYV, 1, 0); 1860c35d236eSmrg break; 1861c35d236eSmrg 1862c35d236eSmrg case LE4CC('Y','U','Y','2'): 1863c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1864c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1865c35d236eSmrg PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_YUYV, 1, 0); 1866c35d236eSmrg break; 1867c35d236eSmrg 1868c35d236eSmrg case LE4CC('U','Y','V','Y'): 1869c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1870c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1871c35d236eSmrg PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_UYVY, 1, 0); 1872c35d236eSmrg break; 1873c35d236eSmrg 1874c35d236eSmrg case LE4CC('Y','U','V','A'): 1875c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1876c35d236eSmrg width << 2, height, pPPriv->BufferStride); 1877c35d236eSmrg PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_YUVA, 2, pPPriv->Attribute[7]); 1878c35d236eSmrg break; 1879c35d236eSmrg 1880c35d236eSmrg case LE4CC('V','U','Y','A'): 1881c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1882c35d236eSmrg width << 2, height, pPPriv->BufferStride); 1883c35d236eSmrg PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_VUYA, 2, pPPriv->Attribute[7]); 1884c35d236eSmrg break; 1885c35d236eSmrg 1886c35d236eSmrg case 0x41: /* RGBA 8:8:8:8 */ 1887c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1888c35d236eSmrg width << 2, height, pPPriv->BufferStride); 1889c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB8888, 2, pPPriv->Attribute[7]); 1890c35d236eSmrg break; 1891c35d236eSmrg 1892c35d236eSmrg case 0x42: /* RGB 5:6:5 */ 1893c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1894c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1895c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB565, 1, 0); 1896c35d236eSmrg break; 1897c35d236eSmrg 1898c35d236eSmrg case 0x43: /* RGB 1:5:5:5 */ 1899c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1900c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1901c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB5551, 1, pPPriv->Attribute[7]); 1902c35d236eSmrg break; 1903c35d236eSmrg 1904c35d236eSmrg case 0x44: /* RGB 4:4:4:4 */ 1905c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1906c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1907c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB4444, 1, pPPriv->Attribute[7]); 1908c35d236eSmrg break; 1909c35d236eSmrg 1910c35d236eSmrg case 0x45: /* RGB 1:2:3:2 */ 1911c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1912c35d236eSmrg width, height, pPPriv->BufferStride); 1913c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB2321, 0, pPPriv->Attribute[7]); 1914c35d236eSmrg break; 1915c35d236eSmrg 1916c35d236eSmrg case 0x46: /* RGB 2:3:3 */ 1917c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1918c35d236eSmrg width, height, pPPriv->BufferStride); 1919c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB332, 0, 0); 1920c35d236eSmrg break; 1921c35d236eSmrg 1922c35d236eSmrg case 0x47: /* BGRA 8:8:8:8 */ 1923c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1924c35d236eSmrg width << 2, height, pPPriv->BufferStride); 1925c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR8888, 2, pPPriv->Attribute[7]); 1926c35d236eSmrg break; 1927c35d236eSmrg 1928c35d236eSmrg case 0x48: /* BGR 5:6:5 */ 1929c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1930c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1931c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR565, 1, 0); 1932c35d236eSmrg break; 1933c35d236eSmrg 1934c35d236eSmrg case 0x49: /* BGR 1:5:5:5 */ 1935c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1936c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1937c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR5551, 1, pPPriv->Attribute[7]); 1938c35d236eSmrg break; 1939c35d236eSmrg 1940c35d236eSmrg case 0x4A: /* BGR 4:4:4:4 */ 1941c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1942c35d236eSmrg width << 1, height, pPPriv->BufferStride); 1943c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR4444, 1, pPPriv->Attribute[7]); 1944c35d236eSmrg break; 1945c35d236eSmrg 1946c35d236eSmrg case 0x4B: /* BGR 1:2:3:2 */ 1947c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1948c35d236eSmrg width << 0, height, pPPriv->BufferStride); 1949c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR2321, 0, pPPriv->Attribute[7]); 1950c35d236eSmrg break; 1951c35d236eSmrg 1952c35d236eSmrg case 0x4C: /* BGR 2:3:3 */ 1953c35d236eSmrg CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], 1954c35d236eSmrg width << 0, height, pPPriv->BufferStride); 1955c35d236eSmrg PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR332, 0, 0); 1956c35d236eSmrg break; 1957c35d236eSmrg 1958c35d236eSmrg default: 1959c35d236eSmrg return XvBadAlloc; 1960c35d236eSmrg } 1961c35d236eSmrg 1962c35d236eSmrg pPPriv->StopDelay = pAPriv->Delay; 1963c35d236eSmrg 1964c35d236eSmrg if (!pAPriv->TimerUsers) { 1965c35d236eSmrg pAPriv->TimerUsers |= 1 << PORTNUM(pPPriv); 1966c35d236eSmrg TimerSet(pAPriv->Timer, 0, 80, TimerCallback, pAPriv); 1967c35d236eSmrg } 1968c35d236eSmrg 1969c35d236eSmrg if (sync) /* sched_yield? */ 1970c35d236eSmrg Permedia2Sync(pScrn); 1971c35d236eSmrg 1972c35d236eSmrg return Success; 1973c35d236eSmrg} 1974c35d236eSmrg 1975c35d236eSmrgstatic void 1976c35d236eSmrgPermedia2StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 1977c35d236eSmrg{ 1978c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 1979c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 1980c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 1981c35d236eSmrg 1982c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 1983c35d236eSmrg "StopVideo port=%d, shutdown=%d\n", PORTNUM(pPPriv), shutdown)); 1984c35d236eSmrg 1985c35d236eSmrg if (shutdown) { 1986c35d236eSmrg if (PORTNUM(pPPriv) < 2) { 1987c35d236eSmrg StopVideoStream(pPPriv, TRUE); 1988c35d236eSmrg RestoreVideoStd(pAPriv); 1989c35d236eSmrg } else { 1990c35d236eSmrg FreeBuffers(pPPriv); 1991c35d236eSmrg FreeCookies(pPPriv); 1992c35d236eSmrg if (pAPriv->TimerUsers) { 1993c35d236eSmrg pAPriv->TimerUsers &= ~PORTNUM(pPPriv); 1994c35d236eSmrg if (!pAPriv->TimerUsers) 1995c35d236eSmrg TimerCancel(pAPriv->Timer); 1996c35d236eSmrg } 1997c35d236eSmrg } 1998c35d236eSmrg } else { 1999c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 2000c35d236eSmrg pPPriv->StopDelay = 750; /* appx. 30 sec */ 2001c35d236eSmrg 2002c35d236eSmrg if (pGlint->NoAccel) 2003c35d236eSmrg Permedia2Sync(pScrn); 2004c35d236eSmrg } 2005c35d236eSmrg} 2006c35d236eSmrg 2007c35d236eSmrgstatic void 2008c35d236eSmrgRestartVideo(PortPrivPtr pPPriv, int old_VideoOn) 2009c35d236eSmrg{ 2010c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 2011c35d236eSmrg int new_fh; 2012c35d236eSmrg 2013c35d236eSmrg if (pPPriv->VideoOn > VIDEO_OFF || 2014c35d236eSmrg pAPriv->VideoStd < 0 /* invalid */) 2015c35d236eSmrg return; 2016c35d236eSmrg 2017c35d236eSmrg new_fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >> 2018c35d236eSmrg (1 - (pPPriv->Attribute[4] & 1)); 2019c35d236eSmrg 2020c35d236eSmrg if (new_fh != pPPriv->fh) { 2021c35d236eSmrg pPPriv->vy = (pPPriv->vy * new_fh) / pPPriv->fh; 2022c35d236eSmrg pPPriv->vh = (pPPriv->vh * new_fh) / pPPriv->fh; 2023c35d236eSmrg 2024c35d236eSmrg pPPriv->fh = new_fh; 2025c35d236eSmrg } 2026c35d236eSmrg 2027c35d236eSmrg if (old_VideoOn) { 2028c35d236eSmrg if (StartVideoStream(pPPriv, NULL)) { 2029c35d236eSmrg pPPriv->VideoOn = old_VideoOn; 2030c35d236eSmrg 2031c35d236eSmrg if (pPPriv == &pAPriv->Port[1]) 2032c35d236eSmrg GetYUV(pPPriv); 2033c35d236eSmrg } else { 2034c35d236eSmrg DEBUG(xf86DrvMsgVerb(pAPriv->pScrn->scrnIndex, X_INFO, 4, 2035c35d236eSmrg "RestartVideo port=%d suspend\n", PORTNUM(pPPriv))); 2036c35d236eSmrg pPPriv->VideoOn = -old_VideoOn; /* suspend (not off) */ 2037c35d236eSmrg } 2038c35d236eSmrg } 2039c35d236eSmrg} 2040c35d236eSmrg 2041c35d236eSmrgstatic int 2042c35d236eSmrgPermedia2SetPortAttribute(ScrnInfoPtr pScrn, 2043c35d236eSmrg Atom attribute, INT32 value, pointer data) 2044c35d236eSmrg{ 2045c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 2046c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 2047c35d236eSmrg int old_VideoStd, old_Plug; 2048c35d236eSmrg int VideoStd = -1, Plug = 0; 2049c35d236eSmrg int r; 2050c35d236eSmrg 2051c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 2052c35d236eSmrg "SPA attr=%d val=%d port=%d\n", 2053c35d236eSmrg attribute, value, PORTNUM(pPPriv))); 2054c35d236eSmrg 2055c35d236eSmrg if (attribute == xvFilter) { 2056c35d236eSmrg pPPriv->Attribute[5] = !!value; 2057c35d236eSmrg return Success; 2058c35d236eSmrg } else if (attribute == xvAlpha) { 2059c35d236eSmrg pPPriv->Attribute[7] = !!value; 2060c35d236eSmrg return Success; 2061c35d236eSmrg } 2062c35d236eSmrg 2063c35d236eSmrg if (PORTNUM(pPPriv) >= 2) 2064c35d236eSmrg return BadMatch; 2065c35d236eSmrg 2066c35d236eSmrg if (attribute == xvInterlace) { 2067c35d236eSmrg int old_value = pPPriv->Attribute[4]; 2068c35d236eSmrg 2069c35d236eSmrg value %= 3; 2070c35d236eSmrg 2071c35d236eSmrg if (value != old_value) { 2072c35d236eSmrg int old_VideoOn = ABS(pPPriv->VideoOn); 2073c35d236eSmrg#if 0 2074c35d236eSmrg if (old_VideoOn) 2075c35d236eSmrg return XvBadAlloc; 2076c35d236eSmrg#endif 2077c35d236eSmrg StopVideoStream(pPPriv, FALSE); 2078c35d236eSmrg FreeBuffers(pPPriv); 2079c35d236eSmrg pPPriv->Attribute[4] = value; 2080c35d236eSmrg RestartVideo(pPPriv, old_VideoOn); 2081c35d236eSmrg 2082c35d236eSmrg if (pPPriv->VideoOn < 0 /* suspended */) { 2083c35d236eSmrg pPPriv->Attribute[4] = old_value; 2084c35d236eSmrg RestartVideo(pPPriv, old_VideoOn); 2085c35d236eSmrg return XvBadAlloc; 2086c35d236eSmrg } 2087c35d236eSmrg } 2088c35d236eSmrg 2089c35d236eSmrg return Success; 2090c35d236eSmrg } 2091c35d236eSmrg 2092c35d236eSmrg if (pPPriv == &pAPriv->Port[0]) { 2093c35d236eSmrg /* 2094c35d236eSmrg * Input 2095c35d236eSmrg */ 2096c35d236eSmrg if (attribute == xvEncoding) { 2097c35d236eSmrg if (value < 0 || value > ENTRIES(InputVideoEncodings)) 2098c35d236eSmrg return XvBadEncoding; 2099c35d236eSmrg 2100c35d236eSmrg VideoStd = value / 3; 2101c35d236eSmrg Plug = value % 3; 2102c35d236eSmrg 2103c35d236eSmrg /* Fall through */ 2104c35d236eSmrg 2105c35d236eSmrg } else if (attribute == xvBrightness) 2106c35d236eSmrg return SetAttr(&pAPriv->Port[0], 0, value); 2107c35d236eSmrg else if (attribute == xvContrast) 2108c35d236eSmrg return SetAttr(&pAPriv->Port[0], 1, value); 2109c35d236eSmrg else if (attribute == xvSaturation) 2110c35d236eSmrg return SetAttr(&pAPriv->Port[0], 2, value); 2111c35d236eSmrg else if (attribute == xvHue) 2112c35d236eSmrg return SetAttr(&pAPriv->Port[0], 3, value); 2113c35d236eSmrg } else { 2114c35d236eSmrg /* 2115c35d236eSmrg * Output 2116c35d236eSmrg */ 2117c35d236eSmrg if (attribute == xvEncoding) { 2118c35d236eSmrg if (value < 0 || value > ENTRIES(OutputVideoEncodings)) 2119c35d236eSmrg return XvBadEncoding; 2120c35d236eSmrg 2121c35d236eSmrg VideoStd = value / 2; 2122c35d236eSmrg Plug = (value % 2) + 1; 2123c35d236eSmrg 2124c35d236eSmrg /* Fall through */ 2125c35d236eSmrg 2126c35d236eSmrg } else if (attribute == xvBkgColor) 2127c35d236eSmrg return SetBkgCol(pPPriv, value); 2128c35d236eSmrg#if 1 2129c35d236eSmrg else if (attribute == xvBrightness || 2130c35d236eSmrg attribute == xvContrast || 2131c35d236eSmrg attribute == xvSaturation || 2132c35d236eSmrg attribute == xvHue) 2133c35d236eSmrg return Success; 2134c35d236eSmrg#endif 2135c35d236eSmrg } 2136c35d236eSmrg 2137c35d236eSmrg if (attribute != xvEncoding) 2138c35d236eSmrg return BadMatch; 2139c35d236eSmrg 2140c35d236eSmrg old_VideoStd = pAPriv->VideoStd; 2141c35d236eSmrg old_Plug = pPPriv->Plug; 2142c35d236eSmrg 2143c35d236eSmrg#if 0 2144c35d236eSmrg if (pAPriv->Port[0].VideoOn || 2145c35d236eSmrg pAPriv->Port[1].VideoOn) 2146c35d236eSmrg return XvBadAlloc; 2147c35d236eSmrg#endif 2148c35d236eSmrg 2149c35d236eSmrg if (Plug != old_Plug) 2150c35d236eSmrg if ((r = SetPlug(pPPriv, Plug)) != Success) 2151c35d236eSmrg return r; 2152c35d236eSmrg 2153c35d236eSmrg if (VideoStd != old_VideoStd) { 2154c35d236eSmrg int old_VideoOn0 = ABS(pAPriv->Port[0].VideoOn); 2155c35d236eSmrg int old_VideoOn1 = ABS(pAPriv->Port[1].VideoOn); 2156c35d236eSmrg 2157c35d236eSmrg StopVideoStream(&pAPriv->Port[0], FALSE); 2158c35d236eSmrg StopVideoStream(&pAPriv->Port[1], FALSE); 2159c35d236eSmrg 2160c35d236eSmrg if (VideoStd == NTSC || pAPriv->VideoStd == NTSC) { 2161c35d236eSmrg FreeBuffers(&pAPriv->Port[0]); 2162c35d236eSmrg FreeBuffers(&pAPriv->Port[1]); 2163c35d236eSmrg } 2164c35d236eSmrg 2165c35d236eSmrg if (SetVideoStd(pPPriv, VideoStd) == Success) { 2166c35d236eSmrg RestartVideo(&pAPriv->Port[0], old_VideoOn0); 2167c35d236eSmrg RestartVideo(&pAPriv->Port[1], old_VideoOn1); 2168c35d236eSmrg } 2169c35d236eSmrg 2170c35d236eSmrg if (pAPriv->Port[0].VideoOn < 0 || 2171c35d236eSmrg pAPriv->Port[1].VideoOn < 0 || 2172c35d236eSmrg VideoStd != pAPriv->VideoStd) { 2173c35d236eSmrg if (SetVideoStd(pPPriv, old_VideoStd) == Success) { 2174c35d236eSmrg RestartVideo(&pAPriv->Port[0], old_VideoOn0); 2175c35d236eSmrg RestartVideo(&pAPriv->Port[1], old_VideoOn1); 2176c35d236eSmrg } 2177c35d236eSmrg 2178c35d236eSmrg if (Plug != old_Plug) 2179c35d236eSmrg SetPlug(pPPriv, old_Plug); 2180c35d236eSmrg 2181c35d236eSmrg return XvBadAlloc; 2182c35d236eSmrg } 2183c35d236eSmrg } 2184c35d236eSmrg 2185c35d236eSmrg return Success; 2186c35d236eSmrg} 2187c35d236eSmrg 2188c35d236eSmrgstatic void 2189c35d236eSmrgRestoreVideoStd(AdaptorPrivPtr pAPriv) 2190c35d236eSmrg{ 2191c35d236eSmrg if (pAPriv->Port[0].VideoOn && !pAPriv->Port[1].VideoOn && 2192c35d236eSmrg pAPriv->Port[0].VideoStdReq != pAPriv->VideoStd) 2193c35d236eSmrg Permedia2SetPortAttribute(pAPriv->pScrn, xvEncoding, 2194c35d236eSmrg pAPriv->Port[0].VideoStdReq * 3 + pAPriv->Port[0].Plug, 2195c35d236eSmrg (pointer) &pAPriv->Port[0]); 2196c35d236eSmrg else 2197c35d236eSmrg if (pAPriv->Port[1].VideoOn && !pAPriv->Port[0].VideoOn && 2198c35d236eSmrg pAPriv->Port[1].VideoStdReq != pAPriv->VideoStd) 2199c35d236eSmrg Permedia2SetPortAttribute(pAPriv->pScrn, xvEncoding, 2200c35d236eSmrg pAPriv->Port[2].VideoStdReq * 2 + pAPriv->Port[1].Plug - 1, 2201c35d236eSmrg (pointer) &pAPriv->Port[1]); 2202c35d236eSmrg} 2203c35d236eSmrg 2204c35d236eSmrgstatic int 2205c35d236eSmrgPermedia2GetPortAttribute(ScrnInfoPtr pScrn, 2206c35d236eSmrg Atom attribute, INT32 *value, pointer data) 2207c35d236eSmrg{ 2208c35d236eSmrg PortPrivPtr pPPriv = (PortPrivPtr) data; 2209c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 2210c35d236eSmrg 2211c35d236eSmrg if (PORTNUM(pPPriv) >= 2 && 2212c35d236eSmrg attribute != xvFilter && 2213c35d236eSmrg attribute != xvAlpha) 2214c35d236eSmrg return BadMatch; 2215c35d236eSmrg 2216c35d236eSmrg if (attribute == xvEncoding) { 2217c35d236eSmrg if (pAPriv->VideoStd < 0) 2218c35d236eSmrg return XvBadAlloc; 2219c35d236eSmrg else 2220c35d236eSmrg if (pPPriv == &pAPriv->Port[0]) 2221c35d236eSmrg *value = pAPriv->VideoStd * 3 + pPPriv->Plug; 2222c35d236eSmrg else 2223c35d236eSmrg *value = pAPriv->VideoStd * 2 + pPPriv->Plug - 1; 2224c35d236eSmrg } else if (attribute == xvBrightness) 2225c35d236eSmrg *value = pPPriv->Attribute[0]; 2226c35d236eSmrg else if (attribute == xvContrast) 2227c35d236eSmrg *value = pPPriv->Attribute[1]; 2228c35d236eSmrg else if (attribute == xvSaturation) 2229c35d236eSmrg *value = pPPriv->Attribute[2]; 2230c35d236eSmrg else if (attribute == xvHue) 2231c35d236eSmrg *value = pPPriv->Attribute[3]; 2232c35d236eSmrg else if (attribute == xvInterlace) 2233c35d236eSmrg *value = pPPriv->Attribute[4]; 2234c35d236eSmrg else if (attribute == xvFilter) 2235c35d236eSmrg *value = pPPriv->Attribute[5]; 2236c35d236eSmrg else if (attribute == xvBkgColor) 2237c35d236eSmrg *value = pPPriv->Attribute[6]; 2238c35d236eSmrg else if (attribute == xvAlpha) 2239c35d236eSmrg *value = pPPriv->Attribute[7]; 2240c35d236eSmrg else 2241c35d236eSmrg return BadMatch; 2242c35d236eSmrg 2243c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 2244c35d236eSmrg "GPA attr=%d val=%d port=%d\n", 2245c35d236eSmrg attribute, *value, PORTNUM(pPPriv))); 2246c35d236eSmrg 2247c35d236eSmrg return Success; 2248c35d236eSmrg} 2249c35d236eSmrg 2250c35d236eSmrgstatic void 2251c35d236eSmrgPermedia2QueryBestSize(ScrnInfoPtr pScrn, Bool motion, 2252c35d236eSmrg short vid_w, short vid_h, short drw_w, short drw_h, 2253c35d236eSmrg unsigned int *p_w, unsigned int *p_h, pointer data) 2254c35d236eSmrg{ 2255c35d236eSmrg *p_w = drw_w; 2256c35d236eSmrg *p_h = drw_h; 2257c35d236eSmrg} 2258c35d236eSmrg 2259c35d236eSmrgstatic int 2260c35d236eSmrgPermedia2QueryImageAttributes(ScrnInfoPtr pScrn, 2261c35d236eSmrg int id, unsigned short *width, unsigned short *height, 2262c35d236eSmrg int *pitches, int *offsets) 2263c35d236eSmrg{ 2264c35d236eSmrg int i, pitch; 2265c35d236eSmrg 2266c35d236eSmrg *width = CLAMP(*width, 1, 2047); 2267c35d236eSmrg *height = CLAMP(*height, 1, 2047); 2268c35d236eSmrg 2269c35d236eSmrg if (offsets) 2270c35d236eSmrg offsets[0] = 0; 2271c35d236eSmrg 2272c35d236eSmrg switch (id) { 2273c35d236eSmrg case LE4CC('Y','V','1','2'): /* Planar YVU 4:2:0 (emulated) */ 2274c35d236eSmrg *width = CLAMP((*width + 1) & ~1, 2, 2046); 2275c35d236eSmrg *height = CLAMP((*height + 1) & ~1, 2, 2046); 2276c35d236eSmrg 2277c35d236eSmrg pitch = *width; /* luma component */ 2278c35d236eSmrg 2279c35d236eSmrg if (offsets) { 2280c35d236eSmrg offsets[1] = pitch * *height; 2281c35d236eSmrg offsets[2] = offsets[1] + (offsets[1] >> 2); 2282c35d236eSmrg } 2283c35d236eSmrg 2284c35d236eSmrg if (pitches) { 2285c35d236eSmrg pitches[0] = pitch; 2286c35d236eSmrg pitches[1] = pitches[2] = pitch >> 1; 2287c35d236eSmrg } 2288c35d236eSmrg 2289c35d236eSmrg return pitch * *height * 3 / 2; 2290c35d236eSmrg 2291c35d236eSmrg case LE4CC('Y','U','Y','2'): /* Packed YUYV 4:2:2 */ 2292c35d236eSmrg case LE4CC('U','Y','V','Y'): /* Packed UYVY 4:2:2 */ 2293c35d236eSmrg *width = CLAMP((*width + 1) & ~1, 2, 2046); 2294c35d236eSmrg 2295c35d236eSmrg pitch = *width * 2; 2296c35d236eSmrg 2297c35d236eSmrg if (pitches) 2298c35d236eSmrg pitches[0] = pitch; 2299c35d236eSmrg 2300c35d236eSmrg return pitch * *height; 2301c35d236eSmrg 2302c35d236eSmrg default: 2303c35d236eSmrg for (i = 0; i < ENTRIES(ScalerImages); i++) 2304c35d236eSmrg if (ScalerImages[i].id == id) 2305c35d236eSmrg break; 2306c35d236eSmrg 2307c35d236eSmrg if (i >= ENTRIES(ScalerImages)) 2308c35d236eSmrg break; 2309c35d236eSmrg 2310c35d236eSmrg pitch = *width * (ScalerImages[i].bits_per_pixel >> 3); 2311c35d236eSmrg 2312c35d236eSmrg if (pitches) 2313c35d236eSmrg pitches[0] = pitch; 2314c35d236eSmrg 2315c35d236eSmrg return pitch * *height; 2316c35d236eSmrg } 2317c35d236eSmrg 2318c35d236eSmrg return 0; 2319c35d236eSmrg} 2320c35d236eSmrg 2321c35d236eSmrgstatic void 2322c35d236eSmrgRestoreVideo(AdaptorPrivPtr pAPriv) 2323c35d236eSmrg{ 2324c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); 2325c35d236eSmrg 2326c35d236eSmrg GLINT_WRITE_REG(pAPriv->dFifoControl, PMFifoControl); 2327c35d236eSmrg GLINT_WRITE_REG(0, VSABase + VSControl); 2328c35d236eSmrg GLINT_WRITE_REG(0, VSBBase + VSControl); 2329c35d236eSmrg usleep(160000); 2330c35d236eSmrg GLINT_MASK_WRITE_REG(VS_UnitMode_ROM, ~VS_UnitMode_Mask, VSConfiguration); 2331c35d236eSmrg} 2332c35d236eSmrg 2333c35d236eSmrgstatic void 2334c35d236eSmrgInitializeVideo(AdaptorPrivPtr pAPriv) 2335c35d236eSmrg{ 2336c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); 2337c35d236eSmrg int i; 2338c35d236eSmrg 2339c35d236eSmrg GLINT_WRITE_REG(0, VSABase + VSControl); 2340c35d236eSmrg GLINT_WRITE_REG(0, VSBBase + VSControl); 2341c35d236eSmrg 2342c35d236eSmrg#if 0 2343c35d236eSmrg GLINT_MASK_WRITE_REG(0, ~(VSAIntFlag | VSBIntFlag), IntEnable); 2344c35d236eSmrg GLINT_WRITE_REG(VSAIntFlag | VSBIntFlag, IntFlags); /* Reset */ 2345c35d236eSmrg#endif 2346c35d236eSmrg 2347c35d236eSmrg for (i = 0x0018; i <= 0x00B0; i += 8) { 2348c35d236eSmrg GLINT_WRITE_REG(0, VSABase + i); 2349c35d236eSmrg GLINT_WRITE_REG(0, VSBBase + i); 2350c35d236eSmrg } 2351c35d236eSmrg 2352c35d236eSmrg GLINT_WRITE_REG((0 << 8) | (132 << 0), VSABase + VSFifoControl); 2353c35d236eSmrg GLINT_WRITE_REG((0 << 8) | (132 << 0), VSBBase + VSFifoControl); 2354c35d236eSmrg 2355c35d236eSmrg GLINT_MASK_WRITE_REG( 2356c35d236eSmrg VS_UnitMode_AB8 | 2357c35d236eSmrg VS_GPBusMode_A | 2358c35d236eSmrg /* VS_HRefPolarityA | */ 2359c35d236eSmrg VS_VRefPolarityA | 2360c35d236eSmrg VS_VActivePolarityA | 2361c35d236eSmrg /* VS_UseFieldA | */ 2362c35d236eSmrg VS_FieldPolarityA | 2363c35d236eSmrg /* VS_FieldEdgeA | */ 2364c35d236eSmrg /* VS_VActiveVBIA | */ 2365c35d236eSmrg VS_InterlaceA | 2366c35d236eSmrg VS_ReverseDataA | 2367c35d236eSmrg 2368c35d236eSmrg /* VS_HRefPolarityB | */ 2369c35d236eSmrg VS_VRefPolarityB | 2370c35d236eSmrg VS_VActivePolarityB | 2371c35d236eSmrg /* VS_UseFieldB | */ 2372c35d236eSmrg VS_FieldPolarityB | 2373c35d236eSmrg /* VS_FieldEdgeB | */ 2374c35d236eSmrg /* VS_VActiveVBIB | */ 2375c35d236eSmrg VS_InterlaceB | 2376c35d236eSmrg /* VS_ColorSpaceB_RGB | */ 2377c35d236eSmrg /* VS_ReverseDataB | */ 2378c35d236eSmrg /* VS_DoubleEdgeB | */ 2379c35d236eSmrg 0, ~0x1FFFFE0F, VSConfiguration); 2380c35d236eSmrg 2381c35d236eSmrg pAPriv->dFifoControl = GLINT_READ_REG(PMFifoControl); 2382c35d236eSmrg GLINT_WRITE_REG((12 << 8) | 8, PMFifoControl); 2383c35d236eSmrg} 2384c35d236eSmrg 2385c35d236eSmrgstatic Bool 2386c35d236eSmrgxvipcHandshake(PortPrivPtr pPPriv, int op, Bool block) 2387c35d236eSmrg{ 2388c35d236eSmrg int r; 2389c35d236eSmrg int brake = 150; 2390c35d236eSmrg 2391c35d236eSmrg xvipc.magic = XVIPC_MAGIC; 2392c35d236eSmrg xvipc.op = op; 2393c35d236eSmrg xvipc.block = block; 2394c35d236eSmrg 2395c35d236eSmrg if (pPPriv) { 2396c35d236eSmrg AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; 2397c35d236eSmrg 2398c35d236eSmrg xvipc.pm2p = pAPriv->pm2p; 2399c35d236eSmrg xvipc.pAPriv = pAPriv; 2400c35d236eSmrg xvipc.port = PORTNUM(pPPriv); 2401c35d236eSmrg } else { 2402c35d236eSmrg xvipc.pm2p = (void *) -1; 2403c35d236eSmrg xvipc.pAPriv = NULL; 2404c35d236eSmrg xvipc.port = -1; 2405c35d236eSmrg } 2406c35d236eSmrg 2407c35d236eSmrg for (;;) { 2408c35d236eSmrg if (brake-- <= 0) 2409c35d236eSmrg return FALSE; /* I brake for bugs. */ 2410c35d236eSmrg 2411c35d236eSmrg DEBUG(xf86MsgVerb(X_INFO, 4, 2412c35d236eSmrg "PM2 XVIPC send op=%d bl=%d po=%d a=%d b=%d c=%d\n", 2413c35d236eSmrg xvipc.op, xvipc.block, xvipc.port, xvipc.a, xvipc.b, xvipc.c)); 2414c35d236eSmrg 2415c35d236eSmrg r = ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc); 2416c35d236eSmrg 2417c35d236eSmrg DEBUG(xf86MsgVerb(X_INFO, 4, 2418c35d236eSmrg "PM2 XVIPC recv op=%d bl=%d po=%d a=%d b=%d c=%d err=%d/%d\n", 2419c35d236eSmrg xvipc.op, xvipc.block, xvipc.port, xvipc.a, xvipc.b, xvipc.c, r, errno)); 2420c35d236eSmrg 2421c35d236eSmrg switch (xvipc.op) { 2422c35d236eSmrg case OP_ALLOC: 2423c35d236eSmrg { 2424c35d236eSmrg AdaptorPrivPtr pAPriv = xvipc.pAPriv; 2425c35d236eSmrg ScrnInfoPtr pScrn = pAPriv->pScrn; 2426c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 2427c35d236eSmrg FBAreaPtr pFBArea = NULL; 2428c35d236eSmrg LFBAreaPtr pLFBArea; 2429c35d236eSmrg 2430c35d236eSmrg xvipc.a = -1; 2431c35d236eSmrg 2432c35d236eSmrg pLFBArea = xalloc(sizeof(LFBAreaRec)); 2433c35d236eSmrg 2434c35d236eSmrg if (pLFBArea) { 2435c35d236eSmrg pLFBArea->pFBArea = pFBArea = 2436c35d236eSmrg xf86AllocateLinearOffscreenArea(pScrn->pScreen, 2437c35d236eSmrg xvipc.b >> BPPSHIFT(pGlint), 2, NULL, NULL, NULL); 2438c35d236eSmrg 2439c35d236eSmrg if (pFBArea) { 2440c35d236eSmrg /* xvipc.a = pFBArea->linear; */ 2441c35d236eSmrg pLFBArea->Linear = xvipc.a = 2442c35d236eSmrg ((pFBArea->box.y1 * pScrn->displayWidth) + 2443c35d236eSmrg pFBArea->box.x1) << BPPSHIFT(pGlint); 2444c35d236eSmrg } else 2445c35d236eSmrg xfree(pLFBArea); 2446c35d236eSmrg } 2447c35d236eSmrg 2448c35d236eSmrg /* Report results */ 2449c35d236eSmrg 2450c35d236eSmrg if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) != 0) 2451c35d236eSmrg if (pFBArea) { 2452c35d236eSmrg xf86FreeOffscreenArea(pFBArea); 2453c35d236eSmrg xfree(pLFBArea); 2454c35d236eSmrg pFBArea = NULL; 2455c35d236eSmrg } 2456c35d236eSmrg 2457c35d236eSmrg if (pFBArea) { 2458c35d236eSmrg pLFBArea->Next = pAPriv->LFBList; 2459c35d236eSmrg pAPriv->LFBList = pLFBArea; 2460c35d236eSmrg } 2461c35d236eSmrg 2462c35d236eSmrg DEBUG(xf86MsgVerb(X_INFO, 3, "PM2 XVIPC alloc addr=%d=0x%08x pFB=%p\n", 2463c35d236eSmrg xvipc.a, xvipc.a, pFBArea)); 2464c35d236eSmrg 2465c35d236eSmrg goto event; 2466c35d236eSmrg } 2467c35d236eSmrg 2468c35d236eSmrg case OP_FREE: 2469c35d236eSmrg { 2470c35d236eSmrg AdaptorPrivPtr pAPriv = xvipc.pAPriv; 2471c35d236eSmrg LFBAreaPtr pLFBArea, *ppLFBArea; 2472c35d236eSmrg 2473c35d236eSmrg for (ppLFBArea = &pAPriv->LFBList; (pLFBArea = *ppLFBArea); 2474c35d236eSmrg ppLFBArea = &pLFBArea->Next) 2475c35d236eSmrg if (pLFBArea->Linear == xvipc.a) 2476c35d236eSmrg break; 2477c35d236eSmrg 2478c35d236eSmrg if (!pLFBArea) 2479c35d236eSmrg xvipc.a = -1; 2480c35d236eSmrg 2481c35d236eSmrg DEBUG(xf86MsgVerb(X_INFO, 3, "PM2 XVIPC free addr=%d=0x%08x pFB=%p\n", 2482c35d236eSmrg xvipc.a, xvipc.a, pLFBArea ? pLFBArea->pFBArea : NULL)); 2483c35d236eSmrg 2484c35d236eSmrg if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) == 0 && pLFBArea) { 2485c35d236eSmrg xf86FreeOffscreenArea(pLFBArea->pFBArea); 2486c35d236eSmrg *ppLFBArea = pLFBArea->Next; 2487c35d236eSmrg xfree(pLFBArea); 2488c35d236eSmrg } 2489c35d236eSmrg 2490c35d236eSmrg goto event; 2491c35d236eSmrg } 2492c35d236eSmrg 2493c35d236eSmrg case OP_UPDATE: 2494c35d236eSmrg { 2495c35d236eSmrg AdaptorPrivPtr pAPriv = xvipc.pAPriv; 2496c35d236eSmrg PortPrivPtr pPPriv; 2497c35d236eSmrg 2498c35d236eSmrg pPPriv = &pAPriv->Port[0]; 2499c35d236eSmrg 2500c35d236eSmrg if (pPPriv->VideoOn > VIDEO_OFF && xvipc.a > 0) { 2501c35d236eSmrg pPPriv->FrameAcc += pPPriv->FramesPerSec; 2502c35d236eSmrg if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { 2503c35d236eSmrg pPPriv->FrameAcc -= pAPriv->FramesPerSec; 2504c35d236eSmrg 2505c35d236eSmrg /* Asynchronous resizing caused by kernel app */ 2506c35d236eSmrg 2507c35d236eSmrg if (xvipc.c != pPPriv->fw || 2508c35d236eSmrg xvipc.d != pPPriv->fh) { 2509c35d236eSmrg pPPriv->vx = (pPPriv->vx * xvipc.c) / pPPriv->fw; 2510c35d236eSmrg pPPriv->vw = (pPPriv->vw * xvipc.c) / pPPriv->fw; 2511c35d236eSmrg pPPriv->vy = (pPPriv->vy * xvipc.d) / pPPriv->fh; 2512c35d236eSmrg pPPriv->vh = (pPPriv->vh * xvipc.d) / pPPriv->fh; 2513c35d236eSmrg 2514c35d236eSmrg pPPriv->fw = xvipc.c; 2515c35d236eSmrg pPPriv->fh = xvipc.d; 2516c35d236eSmrg pPPriv->BufferPProd = xvipc.e; 2517c35d236eSmrg 2518c35d236eSmrg RemakePutCookies(pPPriv, NULL); 2519c35d236eSmrg } 2520c35d236eSmrg 2521c35d236eSmrg PutYUV(pPPriv, xvipc.a, FORMAT_YUYV, 1, 0); 2522c35d236eSmrg 2523c35d236eSmrg if (pPPriv->VideoOn == VIDEO_ONE_SHOT) 2524c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 2525c35d236eSmrg } 2526c35d236eSmrg } else 2527c35d236eSmrg if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { 2528c35d236eSmrg StopVideoStream(pPPriv, TRUE); 2529c35d236eSmrg RestoreVideoStd(pAPriv); 2530c35d236eSmrg } 2531c35d236eSmrg 2532c35d236eSmrg pPPriv = &pAPriv->Port[1]; 2533c35d236eSmrg 2534c35d236eSmrg if (pPPriv->VideoOn > VIDEO_OFF && xvipc.b > 0) { 2535c35d236eSmrg pPPriv->FrameAcc += pPPriv->FramesPerSec; 2536c35d236eSmrg if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { 2537c35d236eSmrg pPPriv->FrameAcc -= pAPriv->FramesPerSec; 2538c35d236eSmrg 2539c35d236eSmrg pPPriv->BufferBase[0] = xvipc.b; 2540c35d236eSmrg 2541c35d236eSmrg /* Output is always exclusive, no async resizing */ 2542c35d236eSmrg 2543c35d236eSmrg GetYUV(pPPriv); 2544c35d236eSmrg 2545c35d236eSmrg if (pPPriv->VideoOn == VIDEO_ONE_SHOT) 2546c35d236eSmrg pPPriv->VideoOn = VIDEO_OFF; 2547c35d236eSmrg } 2548c35d236eSmrg } else 2549c35d236eSmrg if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { 2550c35d236eSmrg StopVideoStream(pPPriv, TRUE); 2551c35d236eSmrg RestoreVideoStd(pAPriv); 2552c35d236eSmrg } 2553c35d236eSmrg 2554c35d236eSmrg /* Fall through */ 2555c35d236eSmrg } 2556c35d236eSmrg 2557c35d236eSmrg default: 2558c35d236eSmrg event: 2559c35d236eSmrg if (xvipc.op == op) 2560c35d236eSmrg return r == 0; 2561c35d236eSmrg 2562c35d236eSmrg xvipc.op = OP_EVENT; 2563c35d236eSmrg xvipc.block = block; 2564c35d236eSmrg } 2565c35d236eSmrg } 2566c35d236eSmrg 2567c35d236eSmrg return TRUE; 2568c35d236eSmrg} 2569c35d236eSmrg 2570c35d236eSmrgstatic void 2571c35d236eSmrgPermedia2ReadInput(int fd, pointer unused) 2572c35d236eSmrg{ 2573c35d236eSmrg xvipcHandshake(NULL, OP_EVENT, FALSE); 2574c35d236eSmrg} 2575c35d236eSmrg 2576c35d236eSmrgstatic Bool 2577c35d236eSmrgxvipcOpen(char *name, ScrnInfoPtr pScrn) 2578c35d236eSmrg{ 2579c35d236eSmrg const char *osname; 2580c35d236eSmrg 2581c35d236eSmrg if (xvipc_fd >= 0) 2582c35d236eSmrg return TRUE; 2583c35d236eSmrg 2584c35d236eSmrg xf86GetOS(&osname, NULL, NULL, NULL); 2585c35d236eSmrg 2586c35d236eSmrg if (!osname || strcmp(osname, "linux")) 2587c35d236eSmrg return FALSE; 2588c35d236eSmrg 2589c35d236eSmrg for (;;) { 2590c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, 2591c35d236eSmrg "XVIPC probing device %s\n", name)); 2592c35d236eSmrg 2593c35d236eSmrg if ((xvipc_fd = open(name, O_RDWR /* | O_TRUNC */, 0)) < 0) 2594c35d236eSmrg break; 2595c35d236eSmrg 2596c35d236eSmrg xvipc.magic = XVIPC_MAGIC; 2597c35d236eSmrg xvipc.pm2p = (void *) -1; 2598c35d236eSmrg xvipc.pAPriv = NULL; 2599c35d236eSmrg xvipc.op = OP_CONNECT; 2600c35d236eSmrg xvipc.a = 0; 2601c35d236eSmrg xvipc.b = 0; 2602c35d236eSmrg xvipc.c = 0; 2603c35d236eSmrg xvipc.d = 0; 2604c35d236eSmrg 2605c35d236eSmrg if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) < 0 || xvipc.pm2p) 2606c35d236eSmrg break; 2607c35d236eSmrg 2608c35d236eSmrg if (xvipc.c != XVIPC_VERSION) { 2609c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2610c35d236eSmrg "Your Permedia 2 kernel driver %d.%d uses XVIPC protocol " 2611c35d236eSmrg "V.%d while this Xv driver expects V.%d. Please update.\n", 2612c35d236eSmrg xvipc.a, xvipc.b, xvipc.c, XVIPC_VERSION); 2613c35d236eSmrg break; 2614c35d236eSmrg } 2615c35d236eSmrg 2616c35d236eSmrg xf86AddInputHandler(xvipc_fd, Permedia2ReadInput, NULL); 2617c35d236eSmrg 2618c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv driver opened %s\n", name); 2619c35d236eSmrg 2620c35d236eSmrg return TRUE; 2621c35d236eSmrg } 2622c35d236eSmrg 2623c35d236eSmrg if (xvipc_fd >= 0) 2624c35d236eSmrg close(xvipc_fd); 2625c35d236eSmrg 2626c35d236eSmrg xvipc_fd = -1; 2627c35d236eSmrg 2628c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Cannot find Permedia 2 kernel driver.\n"); 2629c35d236eSmrg 2630c35d236eSmrg return FALSE; 2631c35d236eSmrg} 2632c35d236eSmrg 2633c35d236eSmrgstatic void 2634c35d236eSmrgDeleteAdaptorPriv(AdaptorPrivPtr pAPriv) 2635c35d236eSmrg{ 2636c35d236eSmrg int i; 2637c35d236eSmrg 2638c35d236eSmrg if (pAPriv->VideoIO) { 2639c35d236eSmrg StopVideoStream(&pAPriv->Port[0], TRUE); 2640c35d236eSmrg StopVideoStream(&pAPriv->Port[1], TRUE); 2641c35d236eSmrg } 2642c35d236eSmrg 2643c35d236eSmrg for (i = 0; i < 6; i++) { 2644c35d236eSmrg FreeBuffers(&pAPriv->Port[i]); 2645c35d236eSmrg FreeCookies(&pAPriv->Port[i]); 2646c35d236eSmrg } 2647c35d236eSmrg 2648c35d236eSmrg TimerFree(pAPriv->Timer); 2649c35d236eSmrg 2650c35d236eSmrg if (pAPriv->VideoIO) { 2651c35d236eSmrg if (pAPriv->pm2p) 2652c35d236eSmrg xvipcHandshake(&pAPriv->Port[0], OP_DISCONNECT, TRUE); 2653c35d236eSmrg else { 2654c35d236eSmrg xf86DestroyI2CDevRec(&pAPriv->Port[0].I2CDev, FALSE); 2655c35d236eSmrg xf86DestroyI2CDevRec(&pAPriv->Port[1].I2CDev, FALSE); 2656c35d236eSmrg 2657c35d236eSmrg RestoreVideo(pAPriv); 2658c35d236eSmrg } 2659c35d236eSmrg } 2660c35d236eSmrg 2661c35d236eSmrg xfree(pAPriv); 2662c35d236eSmrg} 2663c35d236eSmrg 2664c35d236eSmrgstatic AdaptorPrivPtr 2665c35d236eSmrgNewAdaptorPriv(ScrnInfoPtr pScrn, Bool VideoIO) 2666c35d236eSmrg{ 2667c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 2668c35d236eSmrg AdaptorPrivPtr pAPriv = (AdaptorPrivPtr) xcalloc(1, sizeof(AdaptorPrivRec)); 2669c35d236eSmrg int i; 2670c35d236eSmrg 2671c35d236eSmrg if (!pAPriv) 2672c35d236eSmrg return NULL; 2673c35d236eSmrg 2674c35d236eSmrg pAPriv->pScrn = pScrn; 2675c35d236eSmrg 2676c35d236eSmrg for (i = 0; i < PORTS; i++) 2677c35d236eSmrg pAPriv->Port[i].pAdaptor = pAPriv; 2678c35d236eSmrg 2679c35d236eSmrg switch (pScrn->depth) { 2680c35d236eSmrg case 8: 2681c35d236eSmrg pAPriv->dDitherMode = 2682c35d236eSmrg (0 << 10) | /* BGR */ 2683c35d236eSmrg (1 << 1) | /* Dither */ 2684c35d236eSmrg ((5 & 0x10) << 12) | 2685c35d236eSmrg ((5 & 0x0F) << 2) | /* 3:3:2f */ 2686c35d236eSmrg UNIT_ENABLE; 2687c35d236eSmrg pAPriv->dAlphaBlendMode = 2688c35d236eSmrg (0 << 13) | 2689c35d236eSmrg ((5 & 0x10) << 12) | 2690c35d236eSmrg ((5 & 0x0F) << 8) | 2691c35d236eSmrg (84 << 1) | /* Blend (decal) RGB */ 2692c35d236eSmrg UNIT_ENABLE; 2693c35d236eSmrg pAPriv->dTextureDataFormat = 2694c35d236eSmrg (1 << 4) | /* No alpha */ 2695c35d236eSmrg ((14 & 0x10) << 2) | 2696c35d236eSmrg ((14 & 0x0F) << 0); /* CI8 */ 2697c35d236eSmrg break; 2698c35d236eSmrg 2699c35d236eSmrg case 15: 2700c35d236eSmrg pAPriv->dDitherMode = 2701c35d236eSmrg (1 << 10) | /* RGB */ 2702c35d236eSmrg ((1 & 0x10) << 12) | 2703c35d236eSmrg ((1 & 0x0F) << 2) | /* 5:5:5:1f */ 2704c35d236eSmrg UNIT_ENABLE; 2705c35d236eSmrg pAPriv->dAlphaBlendMode = 2706c35d236eSmrg (1 << 13) | 2707c35d236eSmrg ((1 & 0x10) << 12) | 2708c35d236eSmrg ((1 & 0x0F) << 8) | 2709c35d236eSmrg (84 << 1) | 2710c35d236eSmrg UNIT_ENABLE; 2711c35d236eSmrg pAPriv->dTextureDataFormat = 2712c35d236eSmrg (1 << 5) | /* RGB */ 2713c35d236eSmrg (1 << 4) | 2714c35d236eSmrg ((1 & 0x10) << 2) | 2715c35d236eSmrg ((1 & 0x0F) << 0); 2716c35d236eSmrg break; 2717c35d236eSmrg 2718c35d236eSmrg case 16: 2719c35d236eSmrg pAPriv->dDitherMode = 2720c35d236eSmrg (1 << 10) | /* RGB */ 2721c35d236eSmrg ((16 & 0x10) << 12) | 2722c35d236eSmrg ((16 & 0x0F) << 2) | /* 5:6:5f */ 2723c35d236eSmrg UNIT_ENABLE; 2724c35d236eSmrg pAPriv->dAlphaBlendMode = 2725c35d236eSmrg (1 << 13) | 2726c35d236eSmrg ((16 & 0x10) << 12) | 2727c35d236eSmrg ((16 & 0x0F) << 8) | 2728c35d236eSmrg (84 << 1) | 2729c35d236eSmrg UNIT_ENABLE; 2730c35d236eSmrg pAPriv->dTextureDataFormat = 2731c35d236eSmrg (1 << 5) | 2732c35d236eSmrg (1 << 4) | 2733c35d236eSmrg ((16 & 0x10) << 2) | 2734c35d236eSmrg ((16 & 0x0F) << 0); 2735c35d236eSmrg break; 2736c35d236eSmrg 2737c35d236eSmrg case 24: 2738c35d236eSmrg pAPriv->dDitherMode = 2739c35d236eSmrg (1 << 10) | /* RGB */ 2740c35d236eSmrg ((0 & 0x10) << 12) | 2741c35d236eSmrg ((0 & 0x0F) << 2) | /* 8:8:8:8 */ 2742c35d236eSmrg UNIT_ENABLE; 2743c35d236eSmrg pAPriv->dAlphaBlendMode = 2744c35d236eSmrg (1 << 13) | 2745c35d236eSmrg ((0 & 0x10) << 12) | 2746c35d236eSmrg ((0 & 0x0F) << 8) | 2747c35d236eSmrg (84 << 1) | 2748c35d236eSmrg UNIT_ENABLE; 2749c35d236eSmrg pAPriv->dTextureDataFormat = 2750c35d236eSmrg (1 << 5) | 2751c35d236eSmrg (1 << 4) | 2752c35d236eSmrg ((0 & 0x10) << 2) | 2753c35d236eSmrg ((0 & 0x0F) << 0); 2754c35d236eSmrg break; 2755c35d236eSmrg 2756c35d236eSmrg default: 2757c35d236eSmrg xfree(pAPriv); 2758c35d236eSmrg return NULL; 2759c35d236eSmrg } 2760c35d236eSmrg 2761c35d236eSmrg pAPriv->VideoIO = VideoIO; 2762c35d236eSmrg 2763c35d236eSmrg if (VideoIO) { 2764c35d236eSmrg if (xvipc_fd >= 0) { 2765c35d236eSmrg /* Initial handshake, take over control of this head */ 2766c35d236eSmrg 2767c35d236eSmrg xvipc.magic = XVIPC_MAGIC; 2768c35d236eSmrg xvipc.pm2p = (void *) -1; /* Kernel head ID */ 2769c35d236eSmrg xvipc.pAPriv = pAPriv; /* Server head ID */ 2770c35d236eSmrg xvipc.op = OP_CONNECT; 2771c35d236eSmrg 27724f6cd06fSmrg xvipc.a = PCI_DEV_BUS(pGlint->PciInfo); 27734f6cd06fSmrg xvipc.b = PCI_DEV_DEV(pGlint->PciInfo); 27744f6cd06fSmrg xvipc.c = PCI_DEV_FUNC(pGlint->PciInfo); 2775c35d236eSmrg 2776c35d236eSmrg xvipc.d = pScrn->videoRam << 10; /* XF86Config overrides probing */ 2777c35d236eSmrg 2778c35d236eSmrg if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) < 0) { 2779c35d236eSmrg if (errno == EBUSY) 2780c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2781c35d236eSmrg "Another application already opened the Permedia 2 " 2782c35d236eSmrg "kernel driver for this board. To enable " 2783c35d236eSmrg "shared access please start the server first.\n"); 2784c35d236eSmrg else 2785c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2786c35d236eSmrg "Failed to initialize kernel backbone " 2787c35d236eSmrg "due to error %d: %s.\n", errno, strerror(errno)); 2788c35d236eSmrg goto failed; 2789c35d236eSmrg } 2790c35d236eSmrg 2791c35d236eSmrg pAPriv->pm2p = xvipc.pm2p; 2792c35d236eSmrg } else { 2793c35d236eSmrg InitializeVideo(pAPriv); 2794c35d236eSmrg 2795c35d236eSmrg if (!xf86I2CProbeAddress(pGlint->VSBus, SAA7111_SLAVE_ADDRESS)) 2796c35d236eSmrg goto failed; 2797c35d236eSmrg 2798c35d236eSmrg pAPriv->Port[0].I2CDev.DevName = "Decoder SAA 7111A"; 2799c35d236eSmrg pAPriv->Port[0].I2CDev.SlaveAddr = SAA7111_SLAVE_ADDRESS; 2800c35d236eSmrg pAPriv->Port[0].I2CDev.pI2CBus = pGlint->VSBus; 2801c35d236eSmrg 2802c35d236eSmrg if (!xf86I2CDevInit(&pAPriv->Port[0].I2CDev)) 2803c35d236eSmrg goto failed; 2804c35d236eSmrg 2805c35d236eSmrg if (!xf86I2CWriteVec(&pAPriv->Port[0].I2CDev, DecInitVec, ENTRIES(DecInitVec) / 2)) 2806c35d236eSmrg goto failed; 2807c35d236eSmrg 2808c35d236eSmrg if (!xf86I2CProbeAddress(pGlint->VSBus, SAA7125_SLAVE_ADDRESS)) 2809c35d236eSmrg goto failed; 2810c35d236eSmrg 2811c35d236eSmrg pAPriv->Port[1].I2CDev.DevName = "Encoder SAA 7125"; 2812c35d236eSmrg pAPriv->Port[1].I2CDev.SlaveAddr = SAA7125_SLAVE_ADDRESS; 2813c35d236eSmrg pAPriv->Port[1].I2CDev.pI2CBus = pGlint->VSBus; 2814c35d236eSmrg 2815c35d236eSmrg if (!xf86I2CDevInit(&pAPriv->Port[1].I2CDev)) 2816c35d236eSmrg goto failed; 2817c35d236eSmrg 2818c35d236eSmrg if (!xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, EncInitVec, ENTRIES(EncInitVec) / 2)) 2819c35d236eSmrg goto failed; 2820c35d236eSmrg } 2821c35d236eSmrg 2822c35d236eSmrg if (SetVideoStd(&pAPriv->Port[0], PAL) != Success || 2823c35d236eSmrg SetPlug(&pAPriv->Port[0], 0) != Success || /* composite */ 2824c35d236eSmrg SetPlug(&pAPriv->Port[1], 1) != Success) /* composite-adaptor */ 2825c35d236eSmrg goto failed; 2826c35d236eSmrg 2827c35d236eSmrg pAPriv->Port[1].VideoStdReq = pAPriv->Port[0].VideoStdReq; 2828c35d236eSmrg 2829c35d236eSmrg pAPriv->Port[0].BuffersRequested = 2; 2830c35d236eSmrg pAPriv->Port[1].BuffersRequested = 1; 2831c35d236eSmrg 2832c35d236eSmrg for (i = 0; i < 2; i++) { 2833c35d236eSmrg pAPriv->Port[i].fw = 704; 2834c35d236eSmrg pAPriv->Port[i].fh = 576; 2835c35d236eSmrg pAPriv->Port[i].FramesPerSec = 30; 2836c35d236eSmrg pAPriv->Port[i].BufferPProd = partprodPermedia[704 >> 5]; 2837c35d236eSmrg } 2838c35d236eSmrg 2839c35d236eSmrg SetAttr(&pAPriv->Port[0], 0, 0); /* Brightness (-1000..+1000) */ 2840c35d236eSmrg SetAttr(&pAPriv->Port[0], 1, 0); /* Contrast (-3000..+1000) */ 2841c35d236eSmrg SetAttr(&pAPriv->Port[0], 2, 0); /* Color saturation (-3000..+1000) */ 2842c35d236eSmrg SetAttr(&pAPriv->Port[0], 3, 0); /* Hue (-1000..+1000) */ 2843c35d236eSmrg 2844c35d236eSmrg pAPriv->Port[0].Attribute[4] = 1; /* Interlaced (0 = not, 1 = yes, 2845c35d236eSmrg 2 = double scan 50/60 Hz) */ 2846c35d236eSmrg pAPriv->Port[0].Attribute[5] = 0; /* Bilinear Filter (Bool) */ 2847c35d236eSmrg 2848c35d236eSmrg pAPriv->Port[1].Attribute[4] = 1; /* Interlaced (Bool) */ 2849c35d236eSmrg pAPriv->Port[1].Attribute[5] = 0; /* Bilinear Filter (Bool) */ 2850c35d236eSmrg 2851c35d236eSmrg SetBkgCol(&pAPriv->Port[1], 0x000000); /* BkgColor 0x00RRGGBB */ 2852c35d236eSmrg } /* VideoIO */ 2853c35d236eSmrg 2854c35d236eSmrg if (!(pAPriv->Timer = TimerSet(NULL, 0, 0, TimerCallback, pAPriv))) 2855c35d236eSmrg goto failed; 2856c35d236eSmrg 2857c35d236eSmrg for (i = 0; i < PORTS; i++) 2858c35d236eSmrg pAPriv->Port[i].StopDelay = -1; 2859c35d236eSmrg 2860c35d236eSmrg /* Frontend scaler */ 2861c35d236eSmrg 2862c35d236eSmrg for (i = 2; i < 6; i++) { 2863c35d236eSmrg pAPriv->Port[i].fw = 0; 2864c35d236eSmrg pAPriv->Port[i].fh = 0; 2865c35d236eSmrg pAPriv->Port[i].BuffersRequested = 1; 2866c35d236eSmrg pAPriv->Delay = 125; 2867c35d236eSmrg pAPriv->Instant = 1000 / 25; 2868c35d236eSmrg 2869c35d236eSmrg if (!VideoIO || pAPriv->pm2p) { 2870c35d236eSmrg pAPriv->Delay = 5; 2871c35d236eSmrg pAPriv->Instant = 1000; 2872c35d236eSmrg } 2873c35d236eSmrg 2874c35d236eSmrg pAPriv->Port[i].Attribute[5] = 0; /* Bilinear Filter (Bool) */ 2875c35d236eSmrg pAPriv->Port[i].Attribute[7] = 0; /* Alpha Enable (Bool) */ 2876c35d236eSmrg } 2877c35d236eSmrg 2878c35d236eSmrg return pAPriv; 2879c35d236eSmrg 2880c35d236eSmrgfailed: 2881c35d236eSmrg 2882c35d236eSmrg DeleteAdaptorPriv(pAPriv); 2883c35d236eSmrg 2884c35d236eSmrg return NULL; 2885c35d236eSmrg} 2886c35d236eSmrg 2887c35d236eSmrg 2888c35d236eSmrg/* 2889c35d236eSmrg * Glint interface 2890c35d236eSmrg */ 2891c35d236eSmrg 2892c35d236eSmrgvoid 2893c35d236eSmrgPermedia2VideoEnterVT(ScrnInfoPtr pScrn) 2894c35d236eSmrg{ 2895c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 2896c35d236eSmrg AdaptorPrivPtr pAPriv; 2897c35d236eSmrg 2898c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv enter VT\n")); 2899c35d236eSmrg 2900c35d236eSmrg for (pAPriv = AdaptorPrivList; pAPriv != NULL; pAPriv = pAPriv->Next) 2901c35d236eSmrg if (pAPriv->pScrn == pScrn) { 2902c35d236eSmrg if (pAPriv->VideoIO) { 2903c35d236eSmrg if (pAPriv->pm2p) 2904c35d236eSmrg xvipcHandshake(&pAPriv->Port[0], OP_ENTER, TRUE); 2905c35d236eSmrg else { 2906c35d236eSmrg InitializeVideo(pAPriv); 2907c35d236eSmrg 2908c35d236eSmrg xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, EncInitVec, ENTRIES(EncInitVec) / 2); 2909c35d236eSmrg } 2910c35d236eSmrg 2911c35d236eSmrg SetVideoStd(&pAPriv->Port[0], pAPriv->VideoStd); 2912c35d236eSmrg SetPlug(&pAPriv->Port[0], pAPriv->Port[0].Plug); 2913c35d236eSmrg SetPlug(&pAPriv->Port[1], pAPriv->Port[1].Plug); 2914c35d236eSmrg } 2915c35d236eSmrg 2916c35d236eSmrg if (pGlint->NoAccel) 2917c35d236eSmrg Permedia2InitializeEngine(pScrn); 2918c35d236eSmrg 2919c35d236eSmrg break; 2920c35d236eSmrg } 2921c35d236eSmrg} 2922c35d236eSmrg 2923c35d236eSmrgvoid 2924c35d236eSmrgPermedia2VideoLeaveVT(ScrnInfoPtr pScrn) 2925c35d236eSmrg{ 2926c35d236eSmrg AdaptorPrivPtr pAPriv; 2927c35d236eSmrg 2928c35d236eSmrg for (pAPriv = AdaptorPrivList; pAPriv != NULL; pAPriv = pAPriv->Next) 2929c35d236eSmrg if (pAPriv->pScrn == pScrn) { 2930c35d236eSmrg if (pAPriv->VideoIO) { 2931c35d236eSmrg StopVideoStream(&pAPriv->Port[0], TRUE); 2932c35d236eSmrg StopVideoStream(&pAPriv->Port[1], TRUE); 2933c35d236eSmrg 2934c35d236eSmrg if (pAPriv->pm2p) 2935c35d236eSmrg xvipcHandshake(&pAPriv->Port[0], OP_LEAVE, TRUE); 2936c35d236eSmrg else 2937c35d236eSmrg RestoreVideo(pAPriv); 2938c35d236eSmrg } 2939c35d236eSmrg break; 2940c35d236eSmrg } 2941c35d236eSmrg 2942c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Elvis left the building\n")); 2943c35d236eSmrg} 2944c35d236eSmrg 2945c35d236eSmrgvoid 2946c35d236eSmrgPermedia2VideoUninit(ScrnInfoPtr pScrn) 2947c35d236eSmrg{ 2948c35d236eSmrg AdaptorPrivPtr pAPriv, *ppAPriv; 2949c35d236eSmrg 2950c35d236eSmrg for (ppAPriv = &AdaptorPrivList; (pAPriv = *ppAPriv); ppAPriv = &(pAPriv->Next)) 2951c35d236eSmrg if (pAPriv->pScrn == pScrn) { 2952c35d236eSmrg *ppAPriv = pAPriv->Next; 2953c35d236eSmrg DeleteAdaptorPriv(pAPriv); 2954c35d236eSmrg break; 2955c35d236eSmrg } 2956c35d236eSmrg 2957c35d236eSmrg if (xvipc_fd >= 0) { 2958c35d236eSmrg close(xvipc_fd); 2959c35d236eSmrg xvipc_fd = -1; 2960c35d236eSmrg } 2961c35d236eSmrg 2962c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv cleanup\n")); 2963c35d236eSmrg} 2964c35d236eSmrg 2965c35d236eSmrgvoid 2966c35d236eSmrgPermedia2VideoInit(ScreenPtr pScreen) 2967c35d236eSmrg{ 2968c35d236eSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 2969c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 2970c35d236eSmrg AdaptorPrivPtr pAPriv; 2971c35d236eSmrg pointer options[3]; 2972c35d236eSmrg DevUnion Private[PORTS]; 2973c35d236eSmrg XF86VideoAdaptorRec VAR[ADAPTORS]; 2974c35d236eSmrg XF86VideoAdaptorPtr VARPtrs[ADAPTORS]; 2975c35d236eSmrg Bool VideoIO = TRUE; 2976c35d236eSmrg int i; 2977c35d236eSmrg 2978c35d236eSmrg switch (pGlint->Chipset) { 2979c35d236eSmrg case PCI_VENDOR_TI_CHIP_PERMEDIA2: 2980c35d236eSmrg case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: 2981c35d236eSmrg case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: 2982c35d236eSmrg break; 2983c35d236eSmrg 2984c35d236eSmrg default: 2985c35d236eSmrg return; 2986c35d236eSmrg } 2987c35d236eSmrg 2988c35d236eSmrg options[0] = NULL; /* VideoAdaptor "input" subsection options */ 2989c35d236eSmrg options[1] = NULL; /* VideoAdaptor "output" subsection options */ 2990c35d236eSmrg options[2] = NULL; /* VideoAdaptor options */ 2991c35d236eSmrg 2992c35d236eSmrg for (i = 0;; i++) { 2993c35d236eSmrg char *adaptor = NULL; /* receives VideoAdaptor section identifier */ 2994c35d236eSmrg 2995c35d236eSmrg if (!options[0]) 2996c35d236eSmrg options[0] = xf86FindXvOptions(pScreen->myNum, i, "input", &adaptor, options[2] ? NULL : &options[2]); 2997c35d236eSmrg 2998c35d236eSmrg if (!options[1]) 2999c35d236eSmrg options[1] = xf86FindXvOptions(pScreen->myNum, i, "output", &adaptor, options[2] ? NULL : &options[2]); 3000c35d236eSmrg 3001c35d236eSmrg if (!adaptor) { 3002c35d236eSmrg if (!i) /* VideoAdaptor reference enables Xv vio driver */ 3003c35d236eSmrg VideoIO = FALSE; 3004c35d236eSmrg break; 3005c35d236eSmrg } else if (options[0] && options[1]) 3006c35d236eSmrg break; 3007c35d236eSmrg } 3008c35d236eSmrg 30094f6cd06fSmrg if (VideoIO) { 30104f6cd06fSmrg unsigned int temp; 30114f6cd06fSmrg PCI_READ_LONG(pGlint->PciInfo, &temp, PCI_SUBSYSTEM_ID_REG); 30124f6cd06fSmrg switch (temp) { 3013c35d236eSmrg case PCI_SUBSYSTEM_ID_WINNER_2000_P2A: 3014c35d236eSmrg case PCI_SUBSYSTEM_ID_WINNER_2000_P2C: 3015c35d236eSmrg case PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2A: 3016c35d236eSmrg case PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2C: 3017c35d236eSmrg break; 3018c35d236eSmrg 3019c35d236eSmrg default: 3020c35d236eSmrg xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 1, "No Xv vio support for this board\n"); 3021c35d236eSmrg VideoIO = FALSE; 3022c35d236eSmrg } 30234f6cd06fSmrg } 3024c35d236eSmrg if (pGlint->NoAccel && !VideoIO) 3025c35d236eSmrg return; 3026c35d236eSmrg 3027c35d236eSmrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, "Initializing Xv driver rev. 4\n"); 3028c35d236eSmrg 3029c35d236eSmrg if (VideoIO) { 3030c35d236eSmrg for (i = 0; i <= 2; i++) { 3031c35d236eSmrg xf86ProcessOptions(pScrn->scrnIndex, options[i], 3032c35d236eSmrg (i == 0) ? InputOptions : 3033c35d236eSmrg (i == 1) ? OutputOptions : 3034c35d236eSmrg AdaptorOptions); 3035c35d236eSmrg 3036c35d236eSmrg xf86ShowUnusedOptions(pScrn->scrnIndex, options[i]); 3037c35d236eSmrg } 3038c35d236eSmrg 3039c35d236eSmrg if (xf86IsOptionSet(AdaptorOptions, OPTION_DEVICE)) { 3040c35d236eSmrg if (!xvipcOpen(xf86GetOptValString(AdaptorOptions, OPTION_DEVICE), pScrn)) 3041c35d236eSmrg VideoIO = FALSE; 3042c35d236eSmrg } 3043c35d236eSmrg } 3044c35d236eSmrg 3045c35d236eSmrg if (!(pAPriv = NewAdaptorPriv(pScrn, VideoIO))) { 3046c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv driver initialization failed\n"); 3047c35d236eSmrg return; 3048c35d236eSmrg } 3049c35d236eSmrg 3050c35d236eSmrg if (VideoIO) { 3051c35d236eSmrg int n; 3052c35d236eSmrg 3053c35d236eSmrg if (xf86GetOptValInteger(InputOptions, OPTION_BUFFERS, &n)) 3054c35d236eSmrg pAPriv->Port[0].BuffersRequested = CLAMP(n, 1, 2); 3055c35d236eSmrg if (xf86GetOptValInteger(InputOptions, OPTION_FPS, &n)) 3056c35d236eSmrg pAPriv->Port[0].FramesPerSec = CLAMP(n, 1, 30); 3057c35d236eSmrg 3058c35d236eSmrg if (xf86GetOptValInteger(OutputOptions, OPTION_BUFFERS, &n)) 3059c35d236eSmrg pAPriv->Port[1].BuffersRequested = 1; 3060c35d236eSmrg if (xf86GetOptValInteger(OutputOptions, OPTION_FPS, &n)) 3061c35d236eSmrg pAPriv->Port[1].FramesPerSec = CLAMP(n, 1, 30); 3062c35d236eSmrg } 3063c35d236eSmrg 3064c35d236eSmrg if (pGlint->NoAccel) { 3065c35d236eSmrg BoxRec AvailFBArea; 3066c35d236eSmrg 3067c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Xv driver overrides NoAccel option\n"); 3068c35d236eSmrg 3069c35d236eSmrg Permedia2InitializeEngine(pScrn); 3070c35d236eSmrg 3071c35d236eSmrg AvailFBArea.x1 = 0; 3072c35d236eSmrg AvailFBArea.y1 = 0; 3073c35d236eSmrg AvailFBArea.x2 = pScrn->displayWidth; 3074c35d236eSmrg AvailFBArea.y2 = pGlint->FbMapSize / 3075c35d236eSmrg (pScrn->displayWidth * pScrn->bitsPerPixel / 8); 3076c35d236eSmrg 3077c35d236eSmrg xf86InitFBManager(pScreen, &AvailFBArea); 3078c35d236eSmrg } 3079c35d236eSmrg 3080c35d236eSmrg#if defined(XFree86LOADER) && 0 3081c35d236eSmrg if (xf86LoaderCheckSymbol("xf86InitLinearFBManagerRegion")) { 3082c35d236eSmrg int last = pGlint->FbMapSize / (pScrn->bitsPerPixel / 8) - 1; 3083c35d236eSmrg BoxRec AvailFBArea; 3084c35d236eSmrg RegionPtr Region; 3085c35d236eSmrg 3086c35d236eSmrg AvailFBArea.x1 = 0; 3087c35d236eSmrg AvailFBArea.y1 = pScrn->virtualY; 3088c35d236eSmrg AvailFBArea.x2 = last % pScrn->displayWidth + 1; 3089c35d236eSmrg AvailFBArea.y2 = last / pScrn->displayWidth + 1; 3090c35d236eSmrg 3091c35d236eSmrg DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, 3092c35d236eSmrg "Using linear FB %d,%d-%d,%d pitch %d (%dk)\n", 3093c35d236eSmrg AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2, 3094c35d236eSmrg pScrn->displayWidth, (((AvailFBArea.y2 - AvailFBArea.y1) 3095c35d236eSmrg * pScrn->displayWidth) << BPPSHIFT(pGlint)) / 1024)); 3096c35d236eSmrg 3097c35d236eSmrg Region = xf86LinearFBRegion(pScreen, &AvailFBArea, pScrn->displayWidth); 3098c35d236eSmrg xf86InitLinearFBManagerRegion(pScreen, Region); 3099c35d236eSmrg REGION_DESTROY(pScreen, Region); 3100c35d236eSmrg } 3101c35d236eSmrg#endif 3102c35d236eSmrg 3103c35d236eSmrg memset(VAR, 0, sizeof(VAR)); 3104c35d236eSmrg 3105c35d236eSmrg for (i = 0; i < PORTS; i++) 3106c35d236eSmrg Private[i].ptr = (pointer) &pAPriv->Port[i]; 3107c35d236eSmrg 3108c35d236eSmrg for (i = 0; i < ADAPTORS; i++) { 3109c35d236eSmrg VARPtrs[i] = &VAR[i]; 3110c35d236eSmrg switch (i) { 3111c35d236eSmrg case 0: 3112c35d236eSmrg VAR[i].name = "Permedia 2 Video Input"; 3113c35d236eSmrg VAR[i].type = XvInputMask | XvWindowMask | XvVideoMask | XvStillMask; 3114c35d236eSmrg VAR[i].nPorts = 1; 3115c35d236eSmrg VAR[i].pPortPrivates = &Private[0]; 3116c35d236eSmrg VAR[i].nAttributes = ENTRIES(InputVideoAttributes); 3117c35d236eSmrg VAR[i].pAttributes = InputVideoAttributes; 3118c35d236eSmrg VAR[i].nEncodings = ENTRIES(InputVideoEncodings); 3119c35d236eSmrg VAR[i].pEncodings = InputVideoEncodings; 3120c35d236eSmrg VAR[i].nFormats = ENTRIES(InputVideoFormats); 3121c35d236eSmrg VAR[i].pFormats = InputVideoFormats; 3122c35d236eSmrg break; 3123c35d236eSmrg 3124c35d236eSmrg case 1: 3125c35d236eSmrg VAR[i].name = "Permedia 2 Video Output"; 3126c35d236eSmrg VAR[i].type = XvOutputMask | XvWindowMask | XvVideoMask | XvStillMask; 3127c35d236eSmrg VAR[i].nPorts = 1; 3128c35d236eSmrg VAR[i].pPortPrivates = &Private[1]; 3129c35d236eSmrg VAR[i].nAttributes = ENTRIES(OutputVideoAttributes); 3130c35d236eSmrg VAR[i].pAttributes = OutputVideoAttributes; 3131c35d236eSmrg VAR[i].nEncodings = ENTRIES(OutputVideoEncodings); 3132c35d236eSmrg VAR[i].pEncodings = OutputVideoEncodings; 3133c35d236eSmrg VAR[i].nFormats = ENTRIES(OutputVideoFormats); 3134c35d236eSmrg VAR[i].pFormats = OutputVideoFormats; 3135c35d236eSmrg break; 3136c35d236eSmrg 3137c35d236eSmrg case 2: 3138c35d236eSmrg VAR[i].name = "Permedia 2 Frontend Scaler"; 3139c35d236eSmrg VAR[i].type = XvInputMask | XvWindowMask | XvImageMask; 3140c35d236eSmrg VAR[i].nPorts = 3; 3141c35d236eSmrg VAR[i].pPortPrivates = &Private[2]; 3142c35d236eSmrg VAR[i].nAttributes = ENTRIES(ScalerAttributes); 3143c35d236eSmrg VAR[i].pAttributes = ScalerAttributes; 3144c35d236eSmrg VAR[i].nEncodings = ENTRIES(ScalerEncodings); 3145c35d236eSmrg VAR[i].pEncodings = ScalerEncodings; 3146c35d236eSmrg VAR[i].nFormats = ENTRIES(ScalerVideoFormats); 3147c35d236eSmrg VAR[i].pFormats = ScalerVideoFormats; 3148c35d236eSmrg VAR[i].nImages = ENTRIES(ScalerImages); 3149c35d236eSmrg VAR[i].pImages = ScalerImages; 3150c35d236eSmrg break; 3151c35d236eSmrg } 3152c35d236eSmrg 3153c35d236eSmrg VAR[i].PutVideo = Permedia2PutVideo; 3154c35d236eSmrg VAR[i].PutStill = Permedia2PutStill; 3155c35d236eSmrg VAR[i].GetVideo = Permedia2GetVideo; 3156c35d236eSmrg VAR[i].GetStill = Permedia2GetStill; 3157c35d236eSmrg VAR[i].StopVideo = Permedia2StopVideo; 3158c35d236eSmrg VAR[i].SetPortAttribute = Permedia2SetPortAttribute; 3159c35d236eSmrg VAR[i].GetPortAttribute = Permedia2GetPortAttribute; 3160c35d236eSmrg VAR[i].QueryBestSize = Permedia2QueryBestSize; 3161c35d236eSmrg VAR[i].PutImage = Permedia2PutImage; 3162c35d236eSmrg VAR[i].QueryImageAttributes = Permedia2QueryImageAttributes; 3163c35d236eSmrg } 3164c35d236eSmrg 3165c35d236eSmrg if (VideoIO ? xf86XVScreenInit(pScreen, &VARPtrs[0], 3) : 3166c35d236eSmrg xf86XVScreenInit(pScreen, &VARPtrs[2], 1)) { 3167c35d236eSmrg char *s; 3168c35d236eSmrg 3169c35d236eSmrg xvEncoding = MAKE_ATOM(XV_ENCODING); 3170c35d236eSmrg xvHue = MAKE_ATOM(XV_HUE); 3171c35d236eSmrg xvSaturation = MAKE_ATOM(XV_SATURATION); 3172c35d236eSmrg xvBrightness = MAKE_ATOM(XV_BRIGHTNESS); 3173c35d236eSmrg xvContrast = MAKE_ATOM(XV_CONTRAST); 3174c35d236eSmrg xvInterlace = MAKE_ATOM(XV_INTERLACE); 3175c35d236eSmrg xvFilter = MAKE_ATOM(XV_FILTER); 3176c35d236eSmrg xvBkgColor = MAKE_ATOM(XV_BKGCOLOR); 3177c35d236eSmrg xvAlpha = MAKE_ATOM(XV_ALPHA); 3178c35d236eSmrg 3179c35d236eSmrg pAPriv->Next = AdaptorPrivList; 3180c35d236eSmrg AdaptorPrivList = pAPriv; 3181c35d236eSmrg 3182c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv frontend scaler enabled\n"); 3183c35d236eSmrg 3184c35d236eSmrg if (VideoIO) { 3185c35d236eSmrg if ((s = xf86GetOptValString(InputOptions, OPTION_ENCODING))) 3186c35d236eSmrg for (i = 0; i < ENTRIES(InputVideoEncodings); i++) 3187c35d236eSmrg if (!strncmp(s, InputVideoEncodings[i].name, strlen(s))) { 3188c35d236eSmrg Permedia2SetPortAttribute(pScrn, xvEncoding, i, (pointer) &pAPriv->Port[0]); 3189c35d236eSmrg break; 3190c35d236eSmrg } 3191c35d236eSmrg 3192c35d236eSmrg if ((s = xf86GetOptValString(OutputOptions, OPTION_ENCODING))) 3193c35d236eSmrg for (i = 0; i < ENTRIES(OutputVideoEncodings); i++) 3194c35d236eSmrg if (!strncmp(s, OutputVideoEncodings[i].name, strlen(s))) { 3195c35d236eSmrg Permedia2SetPortAttribute(pScrn, xvEncoding, i, (pointer) &pAPriv->Port[1]); 3196c35d236eSmrg break; 3197c35d236eSmrg } 3198c35d236eSmrg 3199c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv vio driver %senabled\n", 3200c35d236eSmrg pAPriv->pm2p ? "with kernel backbone " : ""); 3201c35d236eSmrg } 3202c35d236eSmrg } else { 3203c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n"); 3204c35d236eSmrg DeleteAdaptorPriv(pAPriv); 3205c35d236eSmrg } 3206c35d236eSmrg} 3207