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