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