Home | History | Annotate | Line # | Download | only in src
      1 
      2 #ifdef HAVE_CONFIG_H
      3 #include "config.h"
      4 #endif
      5 
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <stdio.h>
      9 #include <math.h>
     10 
     11 #include "radeon.h"
     12 #include "radeon_reg.h"
     13 #include "radeon_macros.h"
     14 #include "radeon_probe.h"
     15 #include "radeon_video.h"
     16 
     17 #include "xf86.h"
     18 #include "dixstruct.h"
     19 #include "atipciids.h"
     20 #include "xf86fbman.h"
     21 
     22 /* DPMS */
     23 #ifdef HAVE_XEXTPROTO_71
     24 #include <X11/extensions/dpmsconst.h>
     25 #else
     26 #define DPMS_SERVER
     27 #include <X11/extensions/dpms.h>
     28 #endif
     29 
     30 #include <X11/extensions/Xv.h>
     31 #include "fourcc.h"
     32 
     33 #include "theatre_detect.h"
     34 #include "theatre_reg.h"
     35 #include "fi1236.h"
     36 #include "msp3430.h"
     37 #include "tda9885.h"
     38 
     39 #define OFF_DELAY       250  /* milliseconds */
     40 #define FREE_DELAY      15000
     41 
     42 #define OFF_TIMER       0x01
     43 #define FREE_TIMER      0x02
     44 #define CLIENT_VIDEO_ON 0x04
     45 
     46 #define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
     47 
     48 /* capture config constants */
     49 #define BUF_TYPE_FIELD          0
     50 #define BUF_TYPE_ALTERNATING    1
     51 #define BUF_TYPE_FRAME          2
     52 
     53 
     54 #define BUF_MODE_SINGLE         0
     55 #define BUF_MODE_DOUBLE         1
     56 #define BUF_MODE_TRIPLE         2
     57 /* CAP0_CONFIG values */
     58 
     59 #define FORMAT_BROOKTREE        0
     60 #define FORMAT_CCIR656          1
     61 #define FORMAT_ZV               2
     62 #define FORMAT_VIP16            3
     63 #define FORMAT_TRANSPORT        4
     64 
     65 #define ENABLE_RADEON_CAPTURE_WEAVE (RADEON_CAP0_CONFIG_CONTINUOS \
     66                         | (BUF_MODE_DOUBLE <<7) \
     67                         | (BUF_TYPE_FRAME << 4) \
     68                         | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
     69                         | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
     70                         | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
     71                         | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
     72 
     73 #define ENABLE_RADEON_CAPTURE_BOB (RADEON_CAP0_CONFIG_CONTINUOS \
     74                         | (BUF_MODE_SINGLE <<7)  \
     75                         | (BUF_TYPE_ALTERNATING << 4) \
     76                         | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
     77                         | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
     78                         | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
     79                         | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
     80 
     81 
     82 static void RADEONInitOffscreenImages(ScreenPtr);
     83 
     84 static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr);
     85 static int  RADEONPutImage(ScrnInfoPtr, short, short, short, short, short,
     86 			short, short, short, int, unsigned char*, short,
     87 			short, Bool, RegionPtr, pointer,
     88 			DrawablePtr);
     89 static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
     90 static int RADEONPutVideo(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y,
     91                         short src_w, short src_h, short drw_w, short drw_h,
     92 			RegionPtr clipBoxes, pointer data, DrawablePtr pDraw);
     93 
     94 static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv);
     95 static void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
     96 static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv);
     97 static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv);
     98 static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv);
     99 
    100 static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
    101 static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
    102 static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
    103 static Atom xvGamma, xvColorspace;
    104 static Atom xvCRTC;
    105 static Atom xvEncoding, xvFrequency, xvVolume, xvMute,
    106 	     xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
    107 	     xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
    108 	     xvLocationID, xvDeviceID, xvInstanceID, xvDumpStatus,
    109 	     xvAdjustment;
    110 
    111 static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode;
    112 
    113 #define GET_PORT_PRIVATE(pScrn) \
    114    (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
    115 
    116 static void
    117 radeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
    118 {
    119     dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
    120     dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
    121     dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
    122     dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
    123 
    124     if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
    125 	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
    126 }
    127 
    128 static void
    129 radeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
    130 {
    131     if (crtc->enabled) {
    132 	crtc_box->x1 = crtc->x;
    133 	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
    134 	crtc_box->y1 = crtc->y;
    135 	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
    136     } else
    137 	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
    138 }
    139 
    140 static int
    141 radeon_box_area(BoxPtr box)
    142 {
    143     return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
    144 }
    145 
    146 static Bool
    147 radeon_crtc_is_enabled(xf86CrtcPtr crtc)
    148 {
    149     RADEONCrtcPrivatePtr radeon_crtc;
    150 
    151 #ifdef XF86DRM_MODE
    152     if (RADEONPTR(crtc->scrn)->cs) {
    153 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
    154 	return drmmode_crtc->dpms_mode == DPMSModeOn;
    155     }
    156 #endif
    157 
    158     radeon_crtc = crtc->driver_private;
    159     return radeon_crtc->enabled;
    160 }
    161 
    162 xf86CrtcPtr
    163 radeon_pick_best_crtc(ScrnInfoPtr pScrn,
    164 		      int x1, int x2, int y1, int y2)
    165 {
    166     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    167     int			coverage, best_coverage, c;
    168     BoxRec		box, crtc_box, cover_box;
    169     RROutputPtr         primary_output = NULL;
    170     xf86CrtcPtr         best_crtc = NULL, primary_crtc = NULL;
    171 
    172     if (!pScrn->vtSema)
    173 	return NULL;
    174 
    175     box.x1 = x1;
    176     box.x2 = x2;
    177     box.y1 = y1;
    178     box.y2 = y2;
    179     best_coverage = 0;
    180 
    181     /* Prefer the CRTC of the primary output */
    182 #ifdef HAS_DIXREGISTERPRIVATEKEY
    183     if (dixPrivateKeyRegistered(rrPrivKey))
    184 #endif
    185     {
    186 	primary_output = RRFirstOutput(pScrn->pScreen);
    187     }
    188     if (primary_output && primary_output->crtc)
    189 	primary_crtc = primary_output->crtc->devPrivate;
    190 
    191     for (c = 0; c < xf86_config->num_crtc; c++) {
    192 	xf86CrtcPtr crtc = xf86_config->crtc[c];
    193 
    194 	if (!radeon_crtc_is_enabled(crtc))
    195 	    continue;
    196 
    197 	radeon_crtc_box(crtc, &crtc_box);
    198 	radeon_box_intersect(&cover_box, &crtc_box, &box);
    199 	coverage = radeon_box_area(&cover_box);
    200 	if (coverage > best_coverage ||
    201 	    (coverage == best_coverage && crtc == primary_crtc)) {
    202 	    best_crtc = crtc;
    203 	    best_coverage = coverage;
    204 	}
    205     }
    206     return best_crtc;
    207 }
    208 
    209 #ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
    210 static xf86CrtcPtr
    211 radeon_covering_crtc(ScrnInfoPtr pScrn,
    212 		     BoxPtr	box,
    213 		     xf86CrtcPtr desired,
    214 		     BoxPtr	crtc_box_ret)
    215 {
    216     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    217     xf86CrtcPtr		crtc, best_crtc;
    218     int			coverage, best_coverage;
    219     int			c;
    220     BoxRec		crtc_box, cover_box;
    221 
    222     best_crtc = NULL;
    223     best_coverage = 0;
    224     crtc_box_ret->x1 = 0;
    225     crtc_box_ret->x2 = 0;
    226     crtc_box_ret->y1 = 0;
    227     crtc_box_ret->y2 = 0;
    228     for (c = 0; c < xf86_config->num_crtc; c++) {
    229 	crtc = xf86_config->crtc[c];
    230 	radeon_crtc_box(crtc, &crtc_box);
    231 	radeon_box_intersect(&cover_box, &crtc_box, box);
    232 	coverage = radeon_box_area(&cover_box);
    233 	if (coverage && crtc == desired) {
    234 	    *crtc_box_ret = crtc_box;
    235 	    return crtc;
    236 	} else if (coverage > best_coverage) {
    237 	    *crtc_box_ret = crtc_box;
    238 	    best_crtc = crtc;
    239 	    best_coverage = coverage;
    240 	}
    241     }
    242     return best_crtc;
    243 }
    244 
    245 static Bool
    246 radeon_crtc_clip_video_helper(ScrnInfoPtr pScrn,
    247 			      xf86CrtcPtr *crtc_ret,
    248 			      xf86CrtcPtr desired_crtc,
    249 			      BoxPtr      dst,
    250 			      INT32	  *xa,
    251 			      INT32	  *xb,
    252 			      INT32	  *ya,
    253 			      INT32	  *yb,
    254 			      RegionPtr   reg,
    255 			      INT32	  width,
    256 			      INT32	  height)
    257 {
    258     Bool	ret;
    259     RegionRec	crtc_region_local;
    260     RegionPtr	crtc_region = reg;
    261 
    262     /*
    263      * For overlay video, compute the relevant CRTC and
    264      * clip video to that
    265      */
    266     if (crtc_ret) {
    267 	BoxRec		crtc_box;
    268 	xf86CrtcPtr	crtc = radeon_covering_crtc(pScrn, dst,
    269 						    desired_crtc,
    270 						    &crtc_box);
    271 
    272 	if (crtc) {
    273 	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
    274 	    crtc_region = &crtc_region_local;
    275 	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
    276 	}
    277 	*crtc_ret = crtc;
    278     }
    279 
    280     ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb,
    281 				crtc_region, width, height);
    282 
    283     if (crtc_region != reg)
    284 	REGION_UNINIT (pScreen, &crtc_region_local);
    285 
    286     return ret;
    287 }
    288 #endif
    289 
    290 static Bool
    291 radeon_crtc_clip_video(ScrnInfoPtr pScrn,
    292 		       xf86CrtcPtr *crtc_ret,
    293 		       xf86CrtcPtr desired_crtc,
    294 		       BoxPtr      dst,
    295 		       INT32       *xa,
    296 		       INT32       *xb,
    297 		       INT32       *ya,
    298 		       INT32       *yb,
    299 		       RegionPtr   reg,
    300 		       INT32       width,
    301 		       INT32       height)
    302 {
    303 #ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
    304     return radeon_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
    305 				       dst, xa, xb, ya, yb,
    306 				       reg, width, height);
    307 #else
    308     return xf86_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
    309 				       dst, xa, xb, ya, yb,
    310 				       reg, width, height);
    311 #endif
    312 }
    313 
    314 void RADEONInitVideo(ScreenPtr pScreen)
    315 {
    316     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    317     RADEONInfoPtr    info = RADEONPTR(pScrn);
    318     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
    319     XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
    320     XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
    321     int num_adaptors;
    322 
    323     /* no overlay or 3D on RN50 */
    324     if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2)
    325 	    return;
    326 
    327     num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
    328     newAdaptors = malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
    329     if (newAdaptors == NULL)
    330 	return;
    331 
    332     memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
    333     adaptors = newAdaptors;
    334 
    335     if (!IS_AVIVO_VARIANT && !info->kms_enabled) {
    336 	overlayAdaptor = RADEONSetupImageVideo(pScreen);
    337 	if (overlayAdaptor != NULL) {
    338 	    adaptors[num_adaptors++] = overlayAdaptor;
    339 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
    340 	} else
    341 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up overlay video\n");
    342 	RADEONInitOffscreenImages(pScreen);
    343     }
    344 
    345     if ((info->ChipFamily < CHIP_FAMILY_RS400)
    346 #ifdef XF86DRI
    347 	|| (info->directRenderingEnabled)
    348 #endif
    349 	) {
    350 	texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen);
    351 	if (texturedAdaptor != NULL) {
    352 	    adaptors[num_adaptors++] = texturedAdaptor;
    353 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
    354 	} else
    355 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up textured video\n");
    356     } else
    357 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video requires CP on R5xx/R6xx/R7xx/IGP\n");
    358 
    359     if(num_adaptors)
    360 	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
    361 
    362     if(texturedAdaptor) {
    363 	XF86MCAdaptorPtr xvmcAdaptor = RADEONCreateAdaptorXvMC(pScreen, texturedAdaptor->name);
    364 	if(xvmcAdaptor) {
    365 	    if(!xf86XvMCScreenInit(pScreen, 1, &xvmcAdaptor))
    366 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] Failed to initialize extension.\n");
    367 	    else
    368 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Extension initialized.\n");
    369 	}
    370     }
    371 
    372     if(newAdaptors)
    373 	free(newAdaptors);
    374 
    375 }
    376 
    377 /* client libraries expect an encoding */
    378 static XF86VideoEncodingRec DummyEncoding =
    379 {
    380    0,
    381    "XV_IMAGE",
    382    2047, 2047,
    383    {1, 1}
    384 };
    385 
    386  /* the picture is interlaced - hence the half-heights */
    387 
    388 static XF86VideoEncodingRec
    389 InputVideoEncodings[] =
    390 {
    391     { 0, "XV_IMAGE",			2047,2047,{1,1}},
    392     { 1, "pal-composite",		720, 288, { 1, 50 }},
    393     { 2, "pal-tuner",			720, 288, { 1, 50 }},
    394     { 3, "pal-svideo",			720, 288, { 1, 50 }},
    395     { 4, "ntsc-composite",		640, 240, { 1001, 60000 }},
    396     { 5, "ntsc-tuner",			640, 240, { 1001, 60000 }},
    397     { 6, "ntsc-svideo",			640, 240, { 1001, 60000 }},
    398     { 7, "secam-composite",		720, 288, { 1, 50 }},
    399     { 8, "secam-tuner",			720, 288, { 1, 50 }},
    400     { 9, "secam-svideo",		720, 288, { 1, 50 }},
    401     { 10,"pal_60-composite",		768, 288, { 1, 50 }},
    402     { 11,"pal_60-tuner",		768, 288, { 1, 50 }},
    403     { 12,"pal_60-svideo",		768, 288, { 1, 50 }}
    404 };
    405 
    406 
    407 #define NUM_FORMATS 12
    408 
    409 static XF86VideoFormatRec Formats[NUM_FORMATS] =
    410 {
    411    {8, TrueColor}, {8, DirectColor}, {8, PseudoColor},
    412    {8, GrayScale}, {8, StaticGray}, {8, StaticColor},
    413    {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
    414    {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
    415 };
    416 
    417 
    418 #if 0
    419 #define NUM_ATTRIBUTES 9+6
    420 
    421 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
    422 {
    423    {XvSettable             ,     0,    1, "XV_SET_DEFAULTS"},
    424    {XvSettable | XvGettable,     0,    1, "XV_AUTOPAINT_COLORKEY"},
    425    {XvSettable | XvGettable,     0,   ~0, "XV_COLORKEY"},
    426    {XvSettable | XvGettable,     0,    1, "XV_DOUBLE_BUFFER"},
    427    {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
    428    {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
    429    {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
    430    {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
    431    {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
    432    {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
    433    {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
    434    {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
    435    {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
    436    {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
    437    {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
    438 };
    439 
    440 #endif
    441 
    442 #define NUM_ATTRIBUTES 22
    443 #define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12)
    444 
    445 static XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] =
    446 {
    447    {             XvGettable, 0, ~0, "XV_DEVICE_ID"},
    448    {             XvGettable, 0, ~0, "XV_LOCATION_ID"},
    449    {             XvGettable, 0, ~0, "XV_INSTANCE_ID"},
    450    {XvSettable		   , 0, 1, "XV_DUMP_STATUS"},
    451    {XvSettable             , 0, 1, "XV_SET_DEFAULTS"},
    452    {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
    453    {XvSettable | XvGettable, 0, ~0,"XV_COLORKEY"},
    454    {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
    455    {XvSettable | XvGettable,     0,  255, "XV_OVERLAY_ALPHA"},
    456    {XvSettable | XvGettable,     0,  255, "XV_GRAPHICS_ALPHA"},
    457    {XvSettable | XvGettable,     0,    1, "XV_ALPHA_MODE"},
    458    {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
    459    {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
    460    {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
    461    {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
    462    {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
    463    {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
    464    {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
    465    {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
    466    {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
    467    {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
    468    {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
    469 
    470    {XvSettable | XvGettable, -1000, 1000, "XV_DEC_BRIGHTNESS"},
    471    {XvSettable | XvGettable, -1000, 1000, "XV_DEC_CONTRAST"},
    472    {XvSettable | XvGettable, -1000, 1000, "XV_DEC_SATURATION"},
    473    {XvSettable | XvGettable, -1000, 1000, "XV_DEC_HUE"},
    474    {XvSettable | XvGettable, 0, 2, "XV_OVERLAY_DEINTERLACING_METHOD"},
    475    {XvSettable | XvGettable, 0, 12, "XV_ENCODING"},
    476    {XvSettable | XvGettable, 0, -1, "XV_FREQ"},
    477    {             XvGettable, -1000, 1000, "XV_TUNER_STATUS"},
    478    {XvSettable | XvGettable, -1000, 1000, "XV_VOLUME"},
    479    {XvSettable | XvGettable, 0, 1, "XV_MUTE"},
    480    {XvSettable | XvGettable, 0, 1, "XV_SAP"},
    481    {XvSettable | XvGettable, 0, 0x1F, "XV_DEBUG_ADJUSTMENT"},
    482    { 0, 0, 0, NULL}  /* just a place holder so I don't have to be fancy with commas */
    483 };
    484 
    485 
    486 #define INCLUDE_RGB_FORMATS 1
    487 
    488 #if INCLUDE_RGB_FORMATS
    489 
    490 #define NUM_IMAGES 8
    491 
    492 /* Note: GUIDs are bogus... - but nothing uses them anyway */
    493 
    494 /* XXXMRG - xorg-server 21.1.20 defines this differently. */
    495 #undef FOURCC_RGBA32
    496 #define FOURCC_RGBA32   0x41424752
    497 
    498 #define XVIMAGE_RGBA32(byte_order)   \
    499         { \
    500                 FOURCC_RGBA32, \
    501                 XvRGB, \
    502                 byte_order, \
    503                 { 'R', 'G', 'B', 'A', \
    504                   0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
    505                 32, \
    506                 XvPacked, \
    507                 1, \
    508                 32, 0x00FF0000, 0x0000FF00, 0x000000FF, \
    509                 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    510                 {'A', 'R', 'G', 'B', \
    511                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
    512                 XvTopToBottom \
    513         }
    514 
    515 #define FOURCC_RGB24    0x00000000
    516 
    517 #define XVIMAGE_RGB24   \
    518         { \
    519                 FOURCC_RGB24, \
    520                 XvRGB, \
    521                 LSBFirst, \
    522                 { 'R', 'G', 'B', 0, \
    523                   0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
    524                 24, \
    525                 XvPacked, \
    526                 1, \
    527                 24, 0x00FF0000, 0x0000FF00, 0x000000FF, \
    528                 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    529                 { 'R', 'G', 'B', \
    530                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
    531                 XvTopToBottom \
    532         }
    533 
    534 #define FOURCC_RGBT16   0x54424752
    535 
    536 #define XVIMAGE_RGBT16(byte_order)   \
    537         { \
    538                 FOURCC_RGBT16, \
    539                 XvRGB, \
    540                 byte_order, \
    541                 { 'R', 'G', 'B', 'T', \
    542                   0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
    543                 16, \
    544                 XvPacked, \
    545                 1, \
    546                 16, 0x00007C00, 0x000003E0, 0x0000001F, \
    547                 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    548                 {'A', 'R', 'G', 'B', \
    549                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
    550                 XvTopToBottom \
    551         }
    552 
    553 #define FOURCC_RGB16    0x32424752
    554 
    555 #define XVIMAGE_RGB16(byte_order)   \
    556         { \
    557                 FOURCC_RGB16, \
    558                 XvRGB, \
    559                 byte_order, \
    560                 { 'R', 'G', 'B', 0x00, \
    561                   0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
    562                 16, \
    563                 XvPacked, \
    564                 1, \
    565                 16, 0x0000F800, 0x000007E0, 0x0000001F, \
    566                 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    567                 {'R', 'G', 'B', \
    568                   0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
    569                 XvTopToBottom \
    570         }
    571 
    572 static XF86ImageRec Images[NUM_IMAGES] =
    573 {
    574 #if X_BYTE_ORDER == X_BIG_ENDIAN
    575         XVIMAGE_RGBA32(MSBFirst),
    576         XVIMAGE_RGBT16(MSBFirst),
    577         XVIMAGE_RGB16(MSBFirst),
    578 #else
    579         XVIMAGE_RGBA32(LSBFirst),
    580         XVIMAGE_RGBT16(LSBFirst),
    581         XVIMAGE_RGB16(LSBFirst),
    582 #endif
    583         XVIMAGE_RGB24,
    584         XVIMAGE_YUY2,
    585         XVIMAGE_UYVY,
    586         XVIMAGE_YV12,
    587         XVIMAGE_I420
    588 };
    589 
    590 #else
    591 
    592 #define NUM_IMAGES 4
    593 
    594 static XF86ImageRec Images[NUM_IMAGES] =
    595 {
    596     XVIMAGE_YUY2,
    597     XVIMAGE_UYVY,
    598     XVIMAGE_YV12,
    599     XVIMAGE_I420
    600 };
    601 
    602 #endif
    603 
    604 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
    605 static REF_TRANSFORM trans[2] =
    606 {
    607     {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
    608     {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0}  /* BT.709 */
    609 };
    610 
    611 /* Gamma curve definition for preset gammas */
    612 typedef struct tagGAMMA_CURVE_R100
    613 {
    614     uint32_t GAMMA_0_F_SLOPE;
    615     uint32_t GAMMA_0_F_OFFSET;
    616     uint32_t GAMMA_10_1F_SLOPE;
    617     uint32_t GAMMA_10_1F_OFFSET;
    618     uint32_t GAMMA_20_3F_SLOPE;
    619     uint32_t GAMMA_20_3F_OFFSET;
    620     uint32_t GAMMA_40_7F_SLOPE;
    621     uint32_t GAMMA_40_7F_OFFSET;
    622     uint32_t GAMMA_380_3BF_SLOPE;
    623     uint32_t GAMMA_380_3BF_OFFSET;
    624     uint32_t GAMMA_3C0_3FF_SLOPE;
    625     uint32_t GAMMA_3C0_3FF_OFFSET;
    626     float OvGammaCont;
    627 } GAMMA_CURVE_R100;
    628 
    629 typedef struct tagGAMMA_CURVE_R200
    630 {
    631     uint32_t GAMMA_0_F_SLOPE;
    632     uint32_t GAMMA_0_F_OFFSET;
    633     uint32_t GAMMA_10_1F_SLOPE;
    634     uint32_t GAMMA_10_1F_OFFSET;
    635     uint32_t GAMMA_20_3F_SLOPE;
    636     uint32_t GAMMA_20_3F_OFFSET;
    637     uint32_t GAMMA_40_7F_SLOPE;
    638     uint32_t GAMMA_40_7F_OFFSET;
    639     uint32_t GAMMA_80_BF_SLOPE;
    640     uint32_t GAMMA_80_BF_OFFSET;
    641     uint32_t GAMMA_C0_FF_SLOPE;
    642     uint32_t GAMMA_C0_FF_OFFSET;
    643     uint32_t GAMMA_100_13F_SLOPE;
    644     uint32_t GAMMA_100_13F_OFFSET;
    645     uint32_t GAMMA_140_17F_SLOPE;
    646     uint32_t GAMMA_140_17F_OFFSET;
    647     uint32_t GAMMA_180_1BF_SLOPE;
    648     uint32_t GAMMA_180_1BF_OFFSET;
    649     uint32_t GAMMA_1C0_1FF_SLOPE;
    650     uint32_t GAMMA_1C0_1FF_OFFSET;
    651     uint32_t GAMMA_200_23F_SLOPE;
    652     uint32_t GAMMA_200_23F_OFFSET;
    653     uint32_t GAMMA_240_27F_SLOPE;
    654     uint32_t GAMMA_240_27F_OFFSET;
    655     uint32_t GAMMA_280_2BF_SLOPE;
    656     uint32_t GAMMA_280_2BF_OFFSET;
    657     uint32_t GAMMA_2C0_2FF_SLOPE;
    658     uint32_t GAMMA_2C0_2FF_OFFSET;
    659     uint32_t GAMMA_300_33F_SLOPE;
    660     uint32_t GAMMA_300_33F_OFFSET;
    661     uint32_t GAMMA_340_37F_SLOPE;
    662     uint32_t GAMMA_340_37F_OFFSET;
    663     uint32_t GAMMA_380_3BF_SLOPE;
    664     uint32_t GAMMA_380_3BF_OFFSET;
    665     uint32_t GAMMA_3C0_3FF_SLOPE;
    666     uint32_t GAMMA_3C0_3FF_OFFSET;
    667     float OvGammaCont;
    668 } GAMMA_CURVE_R200;
    669 
    670 
    671 /* Preset gammas */
    672 static GAMMA_CURVE_R100 gamma_curve_r100[8] =
    673 {
    674 	/* Gamma 1.0 */
    675 	{0x100, 0x0,
    676 	 0x100, 0x20,
    677 	 0x100, 0x40,
    678 	 0x100, 0x80,
    679 	 0x100, 0x100,
    680 	 0x100, 0x100,
    681 	 1.0},
    682 	/* Gamma 0.85 */
    683 	{0x75,  0x0,
    684 	 0xA2,  0xF,
    685 	 0xAC,  0x23,
    686 	 0xC6,  0x4E,
    687 	 0x129, 0xD6,
    688 	 0x12B, 0xD5,
    689 	 1.0},
    690 	/* Gamma 1.1 */
    691 	{0x180, 0x0,
    692 	 0x13C, 0x30,
    693 	 0x13C, 0x57,
    694 	 0x123, 0xA5,
    695 	 0xEA,  0x116,
    696 	 0xEA, 0x116,
    697 	 0.9913},
    698 	/* Gamma 1.2 */
    699 	{0x21B, 0x0,
    700 	 0x16D, 0x43,
    701 	 0x172, 0x71,
    702 	 0x13D, 0xCD,
    703 	 0xD9,  0x128,
    704 	 0xD6, 0x12A,
    705 	 0.9827},
    706 	/* Gamma 1.45 */
    707 	{0x404, 0x0,
    708 	 0x1B9, 0x81,
    709 	 0x1EE, 0xB8,
    710 	 0x16A, 0x133,
    711 	 0xB7, 0x14B,
    712 	 0xB2, 0x14E,
    713 	 0.9567},
    714 	/* Gamma 1.7 */
    715 	{0x658, 0x0,
    716 	 0x1B5, 0xCB,
    717 	 0x25F, 0x102,
    718 	 0x181, 0x199,
    719 	 0x9C,  0x165,
    720 	 0x98, 0x167,
    721 	 0.9394},
    722 	/* Gamma 2.2 */
    723 	{0x7FF, 0x0,
    724 	 0x625, 0x100,
    725 	 0x1E4, 0x1C4,
    726 	 0x1BD, 0x23D,
    727 	 0x79,  0x187,
    728 	 0x76,  0x188,
    729 	 0.9135},
    730 	/* Gamma 2.5 */
    731 	{0x7FF, 0x0,
    732 	 0x7FF, 0x100,
    733 	 0x2AD, 0x200,
    734 	 0x1A2, 0x2AB,
    735 	 0x6E,  0x194,
    736 	 0x67,  0x197,
    737 	 0.9135}
    738 };
    739 
    740 static GAMMA_CURVE_R200 gamma_curve_r200[8] =
    741  {
    742 	/* Gamma 1.0 */
    743       {0x00000100, 0x00000000,
    744        0x00000100, 0x00000020,
    745        0x00000100, 0x00000040,
    746        0x00000100, 0x00000080,
    747        0x00000100, 0x00000100,
    748        0x00000100, 0x00000100,
    749        0x00000100, 0x00000200,
    750        0x00000100, 0x00000200,
    751        0x00000100, 0x00000300,
    752        0x00000100, 0x00000300,
    753        0x00000100, 0x00000400,
    754        0x00000100, 0x00000400,
    755        0x00000100, 0x00000500,
    756        0x00000100, 0x00000500,
    757        0x00000100, 0x00000600,
    758        0x00000100, 0x00000600,
    759        0x00000100, 0x00000700,
    760        0x00000100, 0x00000700,
    761        1.0},
    762 	/* Gamma 0.85 */
    763       {0x0000001D, 0x00000000,
    764        0x00000028, 0x0000000F,
    765        0x00000056, 0x00000023,
    766        0x000000C5, 0x0000004E,
    767        0x000000DA, 0x000000B0,
    768        0x000000E6, 0x000000AA,
    769        0x000000F1, 0x00000190,
    770        0x000000F9, 0x0000018C,
    771        0x00000101, 0x00000286,
    772        0x00000108, 0x00000282,
    773        0x0000010D, 0x0000038A,
    774        0x00000113, 0x00000387,
    775        0x00000118, 0x0000049A,
    776        0x0000011C, 0x00000498,
    777        0x00000120, 0x000005B4,
    778        0x00000124, 0x000005B2,
    779        0x00000128, 0x000006D6,
    780        0x0000012C, 0x000006D5,
    781        1.0},
    782 	/* Gamma 1.1 */
    783       {0x00000060, 0x00000000,
    784        0x0000004F, 0x00000030,
    785        0x0000009C, 0x00000057,
    786        0x00000121, 0x000000A5,
    787        0x00000113, 0x00000136,
    788        0x0000010B, 0x0000013A,
    789        0x00000105, 0x00000245,
    790        0x00000100, 0x00000247,
    791        0x000000FD, 0x00000348,
    792        0x000000F9, 0x00000349,
    793        0x000000F6, 0x00000443,
    794        0x000000F4, 0x00000444,
    795        0x000000F2, 0x00000538,
    796        0x000000F0, 0x00000539,
    797        0x000000EE, 0x00000629,
    798        0x000000EC, 0x00000629,
    799        0x000000EB, 0x00000716,
    800        0x000000E9, 0x00000717,
    801        0.9913},
    802 	/* Gamma 1.2 */
    803       {0x00000087, 0x00000000,
    804        0x0000005B, 0x00000043,
    805        0x000000B7, 0x00000071,
    806        0x0000013D, 0x000000CD,
    807        0x00000121, 0x0000016B,
    808        0x00000113, 0x00000172,
    809        0x00000107, 0x00000286,
    810        0x000000FF, 0x0000028A,
    811        0x000000F8, 0x00000389,
    812        0x000000F2, 0x0000038B,
    813        0x000000ED, 0x0000047D,
    814        0x000000E9, 0x00000480,
    815        0x000000E5, 0x00000568,
    816        0x000000E1, 0x0000056A,
    817        0x000000DE, 0x0000064B,
    818        0x000000DB, 0x0000064D,
    819        0x000000D9, 0x00000728,
    820        0x000000D6, 0x00000729,
    821        0.9827},
    822 	/* Gamma 1.45 */
    823       {0x00000101, 0x00000000,
    824        0x0000006E, 0x00000081,
    825        0x000000F7, 0x000000B8,
    826        0x0000016E, 0x00000133,
    827        0x00000139, 0x000001EA,
    828        0x0000011B, 0x000001F9,
    829        0x00000105, 0x00000314,
    830        0x000000F6, 0x0000031C,
    831        0x000000E9, 0x00000411,
    832        0x000000DF, 0x00000417,
    833        0x000000D7, 0x000004F6,
    834        0x000000CF, 0x000004F9,
    835        0x000000C9, 0x000005C9,
    836        0x000000C4, 0x000005CC,
    837        0x000000BF, 0x0000068F,
    838        0x000000BA, 0x00000691,
    839        0x000000B6, 0x0000074B,
    840        0x000000B2, 0x0000074D,
    841        0.9567},
    842 	/* Gamma 1.7 */
    843       {0x00000196, 0x00000000,
    844        0x0000006D, 0x000000CB,
    845        0x0000012F, 0x00000102,
    846        0x00000187, 0x00000199,
    847        0x00000144, 0x0000025b,
    848        0x00000118, 0x00000273,
    849        0x000000FE, 0x0000038B,
    850        0x000000E9, 0x00000395,
    851        0x000000DA, 0x0000047E,
    852        0x000000CE, 0x00000485,
    853        0x000000C3, 0x00000552,
    854        0x000000BB, 0x00000556,
    855        0x000000B3, 0x00000611,
    856        0x000000AC, 0x00000614,
    857        0x000000A7, 0x000006C1,
    858        0x000000A1, 0x000006C3,
    859        0x0000009D, 0x00000765,
    860        0x00000098, 0x00000767,
    861        0.9394},
    862 	/* Gamma 2.2 */
    863       {0x000001FF, 0x00000000,
    864        0x0000018A, 0x00000100,
    865        0x000000F1, 0x000001C5,
    866        0x000001D6, 0x0000023D,
    867        0x00000124, 0x00000328,
    868        0x00000116, 0x0000032F,
    869        0x000000E2, 0x00000446,
    870        0x000000D3, 0x0000044D,
    871        0x000000BC, 0x00000520,
    872        0x000000B0, 0x00000526,
    873        0x000000A4, 0x000005D6,
    874        0x0000009B, 0x000005DB,
    875        0x00000092, 0x00000676,
    876        0x0000008B, 0x00000679,
    877        0x00000085, 0x00000704,
    878        0x00000080, 0x00000707,
    879        0x0000007B, 0x00000787,
    880        0x00000076, 0x00000789,
    881        0.9135},
    882 	/* Gamma 2.5 */
    883       {0x000001FF, 0x00000000,
    884        0x000001FF, 0x00000100,
    885        0x00000159, 0x000001FF,
    886        0x000001AC, 0x000002AB,
    887        0x0000012F, 0x00000381,
    888        0x00000101, 0x00000399,
    889        0x000000D9, 0x0000049A,
    890        0x000000C3, 0x000004A5,
    891        0x000000AF, 0x00000567,
    892        0x000000A1, 0x0000056E,
    893        0x00000095, 0x00000610,
    894        0x0000008C, 0x00000614,
    895        0x00000084, 0x000006A0,
    896        0x0000007D, 0x000006A4,
    897        0x00000077, 0x00000721,
    898        0x00000071, 0x00000723,
    899        0x0000006D, 0x00000795,
    900        0x00000068, 0x00000797,
    901        0.9135}
    902 };
    903 
    904 static void
    905 RADEONSetOverlayGamma(ScrnInfoPtr pScrn, uint32_t gamma)
    906 {
    907     RADEONInfoPtr    info = RADEONPTR(pScrn);
    908     unsigned char   *RADEONMMIO = info->MMIO;
    909 
    910     /* Set gamma */
    911     RADEONWaitForIdleMMIO(pScrn);
    912 
    913     if (info->ChipFamily < CHIP_FAMILY_R200) {
    914 	uint32_t ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL) & ~RADEON_SCALER_GAMMA_SEL_MASK;
    915 	OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 5));
    916     }
    917 
    918     /* Load gamma curve adjustments */
    919     if (info->ChipFamily >= CHIP_FAMILY_R200) {
    920     	OUTREG(RADEON_OV0_GAMMA_000_00F,
    921 	    (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
    922 	    (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010));
    923     	OUTREG(RADEON_OV0_GAMMA_010_01F,
    924 	    (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
    925 	    (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
    926     	OUTREG(RADEON_OV0_GAMMA_020_03F,
    927 	    (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
    928 	    (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
    929     	OUTREG(RADEON_OV0_GAMMA_040_07F,
    930 	    (gamma_curve_r200[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
    931 	    (gamma_curve_r200[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
    932     	OUTREG(RADEON_OV0_GAMMA_080_0BF,
    933 	    (gamma_curve_r200[gamma].GAMMA_80_BF_OFFSET << 0x00000000) |
    934 	    (gamma_curve_r200[gamma].GAMMA_80_BF_SLOPE << 0x00000010));
    935     	OUTREG(RADEON_OV0_GAMMA_0C0_0FF,
    936 	    (gamma_curve_r200[gamma].GAMMA_C0_FF_OFFSET << 0x00000000) |
    937 	    (gamma_curve_r200[gamma].GAMMA_C0_FF_SLOPE << 0x00000010));
    938     	OUTREG(RADEON_OV0_GAMMA_100_13F,
    939 	    (gamma_curve_r200[gamma].GAMMA_100_13F_OFFSET << 0x00000000) |
    940 	    (gamma_curve_r200[gamma].GAMMA_100_13F_SLOPE << 0x00000010));
    941     	OUTREG(RADEON_OV0_GAMMA_140_17F,
    942 	    (gamma_curve_r200[gamma].GAMMA_140_17F_OFFSET << 0x00000000) |
    943 	    (gamma_curve_r200[gamma].GAMMA_140_17F_SLOPE << 0x00000010));
    944     	OUTREG(RADEON_OV0_GAMMA_180_1BF,
    945 	    (gamma_curve_r200[gamma].GAMMA_180_1BF_OFFSET << 0x00000000) |
    946 	    (gamma_curve_r200[gamma].GAMMA_180_1BF_SLOPE << 0x00000010));
    947     	OUTREG(RADEON_OV0_GAMMA_1C0_1FF,
    948 	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_OFFSET << 0x00000000) |
    949 	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_SLOPE << 0x00000010));
    950     	OUTREG(RADEON_OV0_GAMMA_200_23F,
    951 	    (gamma_curve_r200[gamma].GAMMA_200_23F_OFFSET << 0x00000000) |
    952 	    (gamma_curve_r200[gamma].GAMMA_200_23F_SLOPE << 0x00000010));
    953     	OUTREG(RADEON_OV0_GAMMA_240_27F,
    954 	    (gamma_curve_r200[gamma].GAMMA_240_27F_OFFSET << 0x00000000) |
    955 	    (gamma_curve_r200[gamma].GAMMA_240_27F_SLOPE << 0x00000010));
    956     	OUTREG(RADEON_OV0_GAMMA_280_2BF,
    957 	    (gamma_curve_r200[gamma].GAMMA_280_2BF_OFFSET << 0x00000000) |
    958 	    (gamma_curve_r200[gamma].GAMMA_280_2BF_SLOPE << 0x00000010));
    959     	OUTREG(RADEON_OV0_GAMMA_2C0_2FF,
    960 	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_OFFSET << 0x00000000) |
    961 	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_SLOPE << 0x00000010));
    962     	OUTREG(RADEON_OV0_GAMMA_300_33F,
    963 	    (gamma_curve_r200[gamma].GAMMA_300_33F_OFFSET << 0x00000000) |
    964 	    (gamma_curve_r200[gamma].GAMMA_300_33F_SLOPE << 0x00000010));
    965     	OUTREG(RADEON_OV0_GAMMA_340_37F,
    966 	    (gamma_curve_r200[gamma].GAMMA_340_37F_OFFSET << 0x00000000) |
    967 	    (gamma_curve_r200[gamma].GAMMA_340_37F_SLOPE << 0x00000010));
    968     	OUTREG(RADEON_OV0_GAMMA_380_3BF,
    969 	    (gamma_curve_r200[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
    970 	    (gamma_curve_r200[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
    971     	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
    972 	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
    973 	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
    974     } else {
    975     	OUTREG(RADEON_OV0_GAMMA_000_00F,
    976 	    (gamma_curve_r100[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
    977 	    (gamma_curve_r100[gamma].GAMMA_0_F_SLOPE << 0x00000010));
    978     	OUTREG(RADEON_OV0_GAMMA_010_01F,
    979 	    (gamma_curve_r100[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
    980 	    (gamma_curve_r100[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
    981     	OUTREG(RADEON_OV0_GAMMA_020_03F,
    982 	    (gamma_curve_r100[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
    983 	    (gamma_curve_r100[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
    984     	OUTREG(RADEON_OV0_GAMMA_040_07F,
    985 	    (gamma_curve_r100[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
    986 	    (gamma_curve_r100[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
    987     	OUTREG(RADEON_OV0_GAMMA_380_3BF,
    988 	    (gamma_curve_r100[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
    989 	    (gamma_curve_r100[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
    990     	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
    991 	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
    992 	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
    993     }
    994 
    995 }
    996 
    997 static uint32_t
    998 RADEONTranslateUserGamma(uint32_t user_gamma)
    999 {
   1000     /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
   1001     if (user_gamma <= 925)       /* 0.85 */
   1002 	return 1;
   1003     else if (user_gamma <= 1050) /* 1.0  */
   1004 	return 0;
   1005     else if (user_gamma <= 1150) /* 1.1  */
   1006 	return 2;
   1007     else if (user_gamma <= 1325) /* 1.2  */
   1008 	return 3;
   1009     else if (user_gamma <= 1575) /* 1.45 */
   1010 	return 4;
   1011     else if (user_gamma <= 1950) /* 1.7  */
   1012 	return 5;
   1013     else if (user_gamma <= 2350) /* 2.2  */
   1014 	return 6;
   1015     else if (user_gamma > 2350)  /* 2.5  */
   1016 	return 7;
   1017     else
   1018 	return 0;
   1019 }
   1020 
   1021 
   1022 /****************************************************************************
   1023  * SetTransform                                                             *
   1024  *  Function: Calculates and sets color space transform from supplied       *
   1025  *            reference transform, gamma, brightness, contrast, hue and     *
   1026  *            saturation.                                                   *
   1027  *    Inputs: bright - brightness                                           *
   1028  *            cont - contrast                                               *
   1029  *            sat - saturation                                              *
   1030  *            hue - hue                                                     *
   1031  *            red_intensity - intensity of red component                    *
   1032  *            green_intensity - intensity of green component                *
   1033  *            blue_intensity - intensity of blue component                  *
   1034  *            ref - index to the table of refernce transforms               *
   1035  *            user_gamma - gamma value x 1000 (e.g., 1200 = gamma of 1.2)   *
   1036  *   Outputs: NONE                                                          *
   1037  ****************************************************************************/
   1038 
   1039 static void RADEONSetTransform (ScrnInfoPtr pScrn,
   1040 				float	    bright,
   1041 				float	    cont,
   1042 				float	    sat,
   1043 				float	    hue,
   1044 				float	    red_intensity,
   1045 				float	    green_intensity,
   1046 				float	    blue_intensity,
   1047 				uint32_t    ref,
   1048 				uint32_t    user_gamma)
   1049 {
   1050     RADEONInfoPtr    info = RADEONPTR(pScrn);
   1051     unsigned char   *RADEONMMIO = info->MMIO;
   1052     float	    OvHueSin, OvHueCos;
   1053     float	    CAdjLuma, CAdjOff;
   1054     float	    CAdjRCb, CAdjRCr;
   1055     float	    CAdjGCb, CAdjGCr;
   1056     float	    CAdjBCb, CAdjBCr;
   1057     float	    RedAdj,GreenAdj,BlueAdj;
   1058     float	    OvLuma, OvROff, OvGOff, OvBOff;
   1059     float	    OvRCb, OvRCr;
   1060     float	    OvGCb, OvGCr;
   1061     float	    OvBCb, OvBCr;
   1062     float	    Loff = 64.0;
   1063     float	    Coff = 512.0f;
   1064 
   1065     uint32_t	    dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff;
   1066     uint32_t	    dwOvRCb, dwOvRCr;
   1067     uint32_t	    dwOvGCb, dwOvGCr;
   1068     uint32_t	    dwOvBCb, dwOvBCr;
   1069     uint32_t	    gamma = 0;
   1070 
   1071     if (ref >= 2)
   1072 	return;
   1073 
   1074     /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
   1075     gamma = RADEONTranslateUserGamma(user_gamma);
   1076 
   1077     if (gamma >= 8)
   1078 	return;
   1079 
   1080     OvHueSin = sin(hue);
   1081     OvHueCos = cos(hue);
   1082 
   1083     CAdjLuma = cont * trans[ref].RefLuma;
   1084     CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0;
   1085     RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0;
   1086     GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0;
   1087     BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0;
   1088 
   1089     CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr;
   1090     CAdjRCr = sat * OvHueCos * trans[ref].RefRCr;
   1091     CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr);
   1092     CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr);
   1093     CAdjBCb = sat * OvHueCos * trans[ref].RefBCb;
   1094     CAdjBCr = sat * OvHueSin * trans[ref].RefBCb;
   1095 
   1096 #if 0 /* default constants */
   1097     CAdjLuma = 1.16455078125;
   1098 
   1099     CAdjRCb = 0.0;
   1100     CAdjRCr = 1.59619140625;
   1101     CAdjGCb = -0.39111328125;
   1102     CAdjGCr = -0.8125;
   1103     CAdjBCb = 2.01708984375;
   1104     CAdjBCr = 0;
   1105 #endif
   1106 
   1107     OvLuma = CAdjLuma * gamma_curve_r100[gamma].OvGammaCont;
   1108     OvRCb = CAdjRCb * gamma_curve_r100[gamma].OvGammaCont;
   1109     OvRCr = CAdjRCr * gamma_curve_r100[gamma].OvGammaCont;
   1110     OvGCb = CAdjGCb * gamma_curve_r100[gamma].OvGammaCont;
   1111     OvGCr = CAdjGCr * gamma_curve_r100[gamma].OvGammaCont;
   1112     OvBCb = CAdjBCb * gamma_curve_r100[gamma].OvGammaCont;
   1113     OvBCr = CAdjBCr * gamma_curve_r100[gamma].OvGammaCont;
   1114     OvROff = RedAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
   1115 	OvLuma * Loff - (OvRCb + OvRCr) * Coff;
   1116     OvGOff = GreenAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
   1117 	OvLuma * Loff - (OvGCb + OvGCr) * Coff;
   1118     OvBOff = BlueAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
   1119 	OvLuma * Loff - (OvBCb + OvBCr) * Coff;
   1120 #if 0 /* default constants */
   1121     OvROff = -888.5;
   1122     OvGOff = 545;
   1123     OvBOff = -1104;
   1124 #endif
   1125 
   1126     OvROff = ClipValue(OvROff, -2048.0, 2047.5);
   1127     OvGOff = ClipValue(OvGOff, -2048.0, 2047.5);
   1128     OvBOff = ClipValue(OvBOff, -2048.0, 2047.5);
   1129     dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff;
   1130     dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff;
   1131     dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff;
   1132 
   1133     if(info->ChipFamily == CHIP_FAMILY_RADEON)
   1134     {
   1135 	dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17;
   1136 	dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1;
   1137 	dwOvRCr = (((INT32)(OvRCr * 2048.0))&0x7fff)<<17;
   1138 	dwOvGCb = (((INT32)(OvGCb * 2048.0))&0x7fff)<<1;
   1139 	dwOvGCr = (((INT32)(OvGCr * 2048.0))&0x7fff)<<17;
   1140 	dwOvBCb = (((INT32)(OvBCb * 2048.0))&0x7fff)<<1;
   1141 	dwOvBCr = (((INT32)(OvBCr * 2048.0))&0x7fff)<<17;
   1142     }
   1143     else
   1144     {
   1145 	dwOvLuma = (((INT32)(OvLuma * 256.0))&0xfff)<<20;
   1146 	dwOvRCb = (((INT32)(OvRCb * 256.0))&0xfff)<<4;
   1147 	dwOvRCr = (((INT32)(OvRCr * 256.0))&0xfff)<<20;
   1148 	dwOvGCb = (((INT32)(OvGCb * 256.0))&0xfff)<<4;
   1149 	dwOvGCr = (((INT32)(OvGCr * 256.0))&0xfff)<<20;
   1150 	dwOvBCb = (((INT32)(OvBCb * 256.0))&0xfff)<<4;
   1151 	dwOvBCr = (((INT32)(OvBCr * 256.0))&0xfff)<<20;
   1152     }
   1153 
   1154     /* set gamma */
   1155     RADEONSetOverlayGamma(pScrn, gamma);
   1156 
   1157     /* color transforms */
   1158     OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma);
   1159     OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr);
   1160     OUTREG(RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma);
   1161     OUTREG(RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr);
   1162     OUTREG(RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma);
   1163     OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr);
   1164 }
   1165 
   1166 static void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode)
   1167 {
   1168     RADEONInfoPtr info = RADEONPTR(pScrn);
   1169     unsigned char *RADEONMMIO = info->MMIO;
   1170 
   1171     if (alpha_mode == 0) { /* key mode */
   1172     	OUTREG(RADEON_OV0_KEY_CNTL,
   1173 		RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */
   1174 		RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */
   1175 		RADEON_CMP_MIX_OR);
   1176     	/* crtc 1 */
   1177     	OUTREG(RADEON_DISP_MERGE_CNTL,
   1178 		(RADEON_DISP_ALPHA_MODE_KEY &
   1179 		RADEON_DISP_ALPHA_MODE_MASK) |
   1180 		((gr_alpha << 0x00000010) &
   1181 		RADEON_DISP_GRPH_ALPHA_MASK) |
   1182 		((ov_alpha << 0x00000018) &
   1183 		RADEON_DISP_OV0_ALPHA_MASK));
   1184     	/* crtc 2 */
   1185     	OUTREG(RADEON_DISP2_MERGE_CNTL,
   1186 		(RADEON_DISP_ALPHA_MODE_KEY &
   1187 		RADEON_DISP_ALPHA_MODE_MASK) |
   1188 		((gr_alpha << 0x00000010) &
   1189 		RADEON_DISP_GRPH_ALPHA_MASK) |
   1190 		((ov_alpha << 0x00000018) &
   1191 		RADEON_DISP_OV0_ALPHA_MASK));
   1192     } else { /* global mode */
   1193     	OUTREG(RADEON_OV0_KEY_CNTL,
   1194 		RADEON_GRAPHIC_KEY_FN_FALSE |   /* what does this do? */
   1195 		RADEON_VIDEO_KEY_FN_FALSE |   /* what does this do? */
   1196 		RADEON_CMP_MIX_AND);
   1197     	/* crtc 2 */
   1198     	OUTREG(RADEON_DISP2_MERGE_CNTL,
   1199 		(RADEON_DISP_ALPHA_MODE_GLOBAL &
   1200 		RADEON_DISP_ALPHA_MODE_MASK) |
   1201 		((gr_alpha << 0x00000010) &
   1202 		RADEON_DISP_GRPH_ALPHA_MASK) |
   1203 		((ov_alpha << 0x00000018) &
   1204 		RADEON_DISP_OV0_ALPHA_MASK));
   1205     	/* crtc 1 */
   1206     	OUTREG(RADEON_DISP_MERGE_CNTL,
   1207 		(RADEON_DISP_ALPHA_MODE_GLOBAL &
   1208 		RADEON_DISP_ALPHA_MODE_MASK) |
   1209 		((gr_alpha << 0x00000010) &
   1210 		RADEON_DISP_GRPH_ALPHA_MASK) |
   1211 		((ov_alpha << 0x00000018) &
   1212 		RADEON_DISP_OV0_ALPHA_MASK));
   1213     }
   1214      /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */
   1215      /* not yet supported */
   1216 }
   1217 
   1218 static void RADEONSetColorKey(ScrnInfoPtr pScrn, uint32_t colorKey)
   1219 {
   1220     RADEONInfoPtr info = RADEONPTR(pScrn);
   1221     unsigned char *RADEONMMIO = info->MMIO;
   1222     uint32_t min, max;
   1223     uint8_t r, g, b;
   1224 
   1225     if (info->CurrentLayout.depth > 8)
   1226     {
   1227 	uint32_t	rbits, gbits, bbits;
   1228 
   1229 	rbits = (colorKey & pScrn->mask.red) >> pScrn->offset.red;
   1230 	gbits = (colorKey & pScrn->mask.green) >> pScrn->offset.green;
   1231 	bbits = (colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
   1232 
   1233 	r = rbits << (8 - pScrn->weight.red);
   1234 	g = gbits << (8 - pScrn->weight.green);
   1235 	b = bbits << (8 - pScrn->weight.blue);
   1236     }
   1237     else
   1238     {
   1239 	uint32_t	bits;
   1240 
   1241 	bits = colorKey & ((1 << info->CurrentLayout.depth) - 1);
   1242 	r = bits;
   1243 	g = bits;
   1244 	b = bits;
   1245     }
   1246     min = (r << 16) | (g << 8) | (b);
   1247     max = (0xff << 24) | (r << 16) | (g << 8) | (b);
   1248 
   1249     RADEONWaitForFifo(pScrn, 2);
   1250     OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max);
   1251     OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min);
   1252 }
   1253 
   1254 void
   1255 RADEONResetVideo(ScrnInfoPtr pScrn)
   1256 {
   1257     RADEONInfoPtr   info      = RADEONPTR(pScrn);
   1258     unsigned char *RADEONMMIO = info->MMIO;
   1259     RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
   1260     char tmp[200];
   1261 
   1262     /* this function is called from ScreenInit. pScreen is used
   1263        by XAA internally, but not valid until ScreenInit finishs.
   1264     */
   1265     if (info->accelOn && pScrn->pScreen)
   1266 	RADEON_SYNC(info, pScrn);
   1267 
   1268     /* this is done here because each time the server is reset these
   1269        could change.. Otherwise they remain constant */
   1270     xvInstanceID = MAKE_ATOM("XV_INSTANCE_ID");
   1271     xvDeviceID = MAKE_ATOM("XV_DEVICE_ID");
   1272     xvLocationID = MAKE_ATOM("XV_LOCATION_ID");
   1273     xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS");
   1274 
   1275     xvBrightness   = MAKE_ATOM("XV_BRIGHTNESS");
   1276     xvSaturation   = MAKE_ATOM("XV_SATURATION");
   1277     xvColor        = MAKE_ATOM("XV_COLOR");
   1278     xvContrast     = MAKE_ATOM("XV_CONTRAST");
   1279     xvColorKey     = MAKE_ATOM("XV_COLORKEY");
   1280     xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
   1281     xvHue          = MAKE_ATOM("XV_HUE");
   1282     xvRedIntensity   = MAKE_ATOM("XV_RED_INTENSITY");
   1283     xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY");
   1284     xvBlueIntensity  = MAKE_ATOM("XV_BLUE_INTENSITY");
   1285     xvGamma          = MAKE_ATOM("XV_GAMMA");
   1286     xvColorspace     = MAKE_ATOM("XV_COLORSPACE");
   1287 
   1288     xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
   1289     xvSetDefaults       = MAKE_ATOM("XV_SET_DEFAULTS");
   1290     xvCRTC              = MAKE_ATOM("XV_CRTC");
   1291 
   1292     xvOvAlpha	      = MAKE_ATOM("XV_OVERLAY_ALPHA");
   1293     xvGrAlpha	      = MAKE_ATOM("XV_GRAPHICS_ALPHA");
   1294     xvAlphaMode       = MAKE_ATOM("XV_ALPHA_MODE");
   1295 
   1296     xvOverlayDeinterlacingMethod = MAKE_ATOM("XV_OVERLAY_DEINTERLACING_METHOD");
   1297 
   1298     xvDecBrightness   = MAKE_ATOM("XV_DEC_BRIGHTNESS");
   1299     xvDecSaturation   = MAKE_ATOM("XV_DEC_SATURATION");
   1300     xvDecColor        = MAKE_ATOM("XV_DEC_COLOR");
   1301     xvDecContrast     = MAKE_ATOM("XV_DEC_CONTRAST");
   1302     xvDecHue          = MAKE_ATOM("XV_DEC_HUE");
   1303 
   1304     xvEncoding        = MAKE_ATOM("XV_ENCODING");
   1305     xvFrequency       = MAKE_ATOM("XV_FREQ");
   1306     xvTunerStatus     = MAKE_ATOM("XV_TUNER_STATUS");
   1307     xvVolume          = MAKE_ATOM("XV_VOLUME");
   1308     xvMute            = MAKE_ATOM("XV_MUTE");
   1309     xvSAP             = MAKE_ATOM("XV_SAP");
   1310 
   1311     xvAdjustment      = MAKE_ATOM("XV_DEBUG_ADJUSTMENT");
   1312 
   1313     sprintf(tmp, "RXXX:%d.%d.%d", PCI_DEV_VENDOR_ID(info->PciInfo),
   1314 	    PCI_DEV_DEVICE_ID(info->PciInfo), PCI_DEV_REVISION(info->PciInfo));
   1315     pPriv->device_id = MAKE_ATOM(tmp);
   1316     sprintf(tmp, "PCI:%02d:%02d.%d", PCI_DEV_BUS(info->PciInfo),
   1317 	    PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo));
   1318     pPriv->location_id = MAKE_ATOM(tmp);
   1319     sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex);
   1320     pPriv->instance_id = MAKE_ATOM(tmp);
   1321 
   1322     OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOFT_RESET);
   1323     OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0);   /* maybe */
   1324     OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0);
   1325     OUTREG(RADEON_OV0_FILTER_CNTL, RADEON_FILTER_PROGRAMMABLE_COEF);
   1326     OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ |
   1327 				RADEON_VIDEO_KEY_FN_FALSE |
   1328 				RADEON_CMP_MIX_OR);
   1329     OUTREG(RADEON_OV0_TEST, 0);
   1330     OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
   1331     OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
   1332     RADEONSetColorKey(pScrn, pPriv->colorKey);
   1333 
   1334     if (info->ChipFamily == CHIP_FAMILY_RADEON) {
   1335 
   1336 	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000);
   1337 	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e);
   1338 	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0);
   1339 	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442);
   1340 	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040);
   1341 	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
   1342 
   1343     } else {
   1344 
   1345 	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000);
   1346 	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e);
   1347 	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da);
   1348 	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442);
   1349 	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046);
   1350 	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
   1351     }
   1352 	/*
   1353 	 * Set default Gamma ramp:
   1354 	 *
   1355 	 * Of 18 segments for gamma curve, all segments in R200 (and
   1356 	 * newer) are programmable, while only lower 4 and upper 2
   1357 	 * segments are programmable in the older Radeons.
   1358 	 */
   1359 
   1360     RADEONSetOverlayGamma(pScrn, 0); /* gamma = 1.0 */
   1361 
   1362     if(pPriv->VIP!=NULL){
   1363         RADEONVIP_reset(pScrn,pPriv);
   1364         }
   1365 
   1366     if(pPriv->theatre != NULL) {
   1367         xf86_InitTheatre(pPriv->theatre);
   1368 /*      xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); */
   1369         }
   1370 
   1371     if(pPriv->i2c != NULL){
   1372         RADEONResetI2C(pScrn, pPriv);
   1373         }
   1374 }
   1375 
   1376 static void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
   1377 {
   1378     RADEONInfoPtr info = RADEONPTR(pScrn);
   1379     RADEONPLLPtr  pll = &(info->pll);
   1380     TheatrePtr t;
   1381 
   1382     uint8_t a;
   1383     int i;
   1384 
   1385     pPriv->theatre = NULL;
   1386 
   1387     if(!info->MM_TABLE_valid &&
   1388        !((info->RageTheatreCrystal>=0) &&
   1389            (info->RageTheatreTunerPort>=0) && (info->RageTheatreCompositePort>=0) &&
   1390            (info->RageTheatreSVideoPort>=0)))
   1391     {
   1392        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no multimedia table present, disabling Rage Theatre.\n");
   1393        return;
   1394     }
   1395 
   1396     /* Go and find Rage Theatre, if it exists */
   1397 
   1398     if (info->IsMobility)
   1399 	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n");
   1400     else
   1401 	pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
   1402 
   1403     if(pPriv->theatre==NULL)return;
   1404 
   1405     /* just a matter of convenience */
   1406     t=pPriv->theatre;
   1407 
   1408     t->video_decoder_type=info->video_decoder_type;
   1409 
   1410     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type is 0x%04x (BIOS value) versus 0x%04x (current PLL setting)\n",
   1411          t->video_decoder_type, pll->xclk);
   1412 
   1413     if(info->MM_TABLE_valid){
   1414          for(i=0;i<5;i++){
   1415                 a=info->MM_TABLE.input[i];
   1416 
   1417                 switch(a & 0x3){
   1418                         case 1:
   1419                                 t->wTunerConnector=i;
   1420                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tuner is on port %d\n",i);
   1421                                 break;
   1422                         case 2:  if(a & 0x4){
   1423                                    t->wComp0Connector=RT_COMP2;
   1424                                    } else {
   1425                                    t->wComp0Connector=RT_COMP1;
   1426                                    }
   1427                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector);
   1428                                   break;
   1429                         case 3:  if(a & 0x4){
   1430                                    t->wSVideo0Connector=RT_YCR_COMP4;
   1431                                    } else {
   1432                                    t->wSVideo0Connector=RT_YCF_COMP4;
   1433                                    }
   1434                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector);
   1435                                    break;
   1436                         default:
   1437                                 break;
   1438                         }
   1439                 }
   1440         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n",
   1441     	     (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
   1442 
   1443          }
   1444 
   1445     if(info->RageTheatreTunerPort>=0)t->wTunerConnector=info->RageTheatreTunerPort;
   1446     if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort;
   1447     if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort;
   1448 
   1449     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n",
   1450     	(unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
   1451 
   1452     switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){
   1453                 case 2700:
   1454                         t->video_decoder_type=RT_FREF_2700;
   1455                         break;
   1456                 case 2950:
   1457                         t->video_decoder_type=RT_FREF_2950;
   1458                         break;
   1459                 default:
   1460                         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1461                                 "Unsupported reference clock frequency, Rage Theatre disabled\n");
   1462                         t->theatre_num=-1;
   1463 			free(pPriv->theatre);
   1464 			pPriv->theatre = NULL;
   1465 			return;
   1466                 }
   1467     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type used: 0x%04x\n", t->video_decoder_type);
   1468 }
   1469 
   1470 static XF86VideoAdaptorPtr
   1471 RADEONAllocAdaptor(ScrnInfoPtr pScrn)
   1472 {
   1473     XF86VideoAdaptorPtr adapt;
   1474     RADEONInfoPtr info = RADEONPTR(pScrn);
   1475     RADEONPortPrivPtr pPriv;
   1476     uint32_t dot_clock;
   1477     int ecp;
   1478 
   1479     if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
   1480 	return NULL;
   1481 
   1482     if(!(pPriv = calloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion))))
   1483     {
   1484 	free(adapt);
   1485 	return NULL;
   1486     }
   1487 
   1488     adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
   1489     adapt->pPortPrivates[0].ptr = (pointer)pPriv;
   1490 
   1491     pPriv->colorKey = info->videoKey;
   1492     pPriv->doubleBuffer = TRUE;
   1493     pPriv->videoStatus = 0;
   1494     pPriv->brightness = 0;
   1495     pPriv->transform_index = 0;
   1496     pPriv->saturation = 0;
   1497     pPriv->contrast = 0;
   1498     pPriv->red_intensity = 0;
   1499     pPriv->green_intensity = 0;
   1500     pPriv->blue_intensity = 0;
   1501     pPriv->hue = 0;
   1502     pPriv->currentBuffer = 0;
   1503     pPriv->autopaint_colorkey = TRUE;
   1504     pPriv->gamma = 1000;
   1505     pPriv->desired_crtc = NULL;
   1506 
   1507     pPriv->ov_alpha = 255;
   1508     pPriv->gr_alpha = 255;
   1509     pPriv->alpha_mode = 0;
   1510 
   1511        /* TV-in stuff */
   1512     pPriv->video_stream_active = FALSE;
   1513     pPriv->encoding = 4;
   1514     pPriv->frequency = 1000;
   1515     pPriv->volume = -1000;
   1516     pPriv->mute = TRUE;
   1517     pPriv->v = 0;
   1518     pPriv->overlay_deinterlacing_method = METHOD_BOB;
   1519     pPriv->capture_vbi_data = 0;
   1520     pPriv->dec_brightness = 0;
   1521     pPriv->dec_saturation = 0;
   1522     pPriv->dec_contrast = 0;
   1523     pPriv->dec_hue = 0;
   1524 
   1525 
   1526     /*
   1527      * Unlike older Mach64 chips, RADEON has only two ECP settings:
   1528      * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
   1529      * for higher clocks, sure makes life nicer
   1530      */
   1531     dot_clock = info->ModeReg->dot_clock_freq;
   1532 
   1533     if (dot_clock < 17500)
   1534         info->ecp_div = 0;
   1535     else
   1536         info->ecp_div = 1;
   1537     ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
   1538 
   1539     if (info->IsIGP) {
   1540         /* Force the overlay clock on for integrated chips
   1541 	 */
   1542         ecp |= (1<<18);
   1543     }
   1544 
   1545     OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp);
   1546 
   1547 
   1548     /* Decide on tuner type */
   1549     if((info->tunerType<0) && (info->MM_TABLE_valid)) {
   1550         pPriv->tuner_type = info->MM_TABLE.tuner_type;
   1551     	} else
   1552         pPriv->tuner_type = info->tunerType;
   1553 
   1554     /* Initialize I2C bus */
   1555     RADEONInitI2C(pScrn, pPriv);
   1556     if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
   1557 
   1558 
   1559     #if 0  /* this is just here for easy debugging - normally off */
   1560     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n");
   1561     for(i=0;i<255;i+=2)
   1562         if(RADEONProbeAddress(pPriv->i2c, i))
   1563                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "     found device at address 0x%02x\n", i);
   1564     #endif
   1565 
   1566     /* resetting the VIP bus causes problems with some mobility chips.
   1567      * we don't support video in on any mobility chips at the moment anyway
   1568      */
   1569     /* Initialize VIP bus */
   1570     if (!info->IsMobility)
   1571 	RADEONVIP_init(pScrn, pPriv);
   1572 
   1573     info->adaptor = adapt;
   1574     info->xv_max_width = 2047;
   1575     info->xv_max_height = 2047;
   1576 
   1577 	if(!xf86LoadSubModule(pScrn,"theatre_detect"))
   1578 	{
   1579 		xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n");
   1580 		goto skip_theatre;
   1581     }
   1582 	RADEONSetupTheatre(pScrn, pPriv);
   1583 
   1584 	/*
   1585 	 * Now load the correspondind theatre chip based on what has been detected.
   1586 	 */
   1587 	if (pPriv->theatre)
   1588 	{
   1589 		xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Going to load the corresponding theatre module\n");
   1590 		switch (pPriv->theatre->theatre_id)
   1591 		{
   1592 			case RT100_ATI_ID:
   1593 			{
   1594 				if(!xf86LoadSubModule(pScrn,"theatre"))
   1595 				{
   1596 					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
   1597 					free(pPriv->theatre);
   1598 					goto skip_theatre;
   1599 				}
   1600 				break;
   1601 			}
   1602 			case RT200_ATI_ID:
   1603 			{
   1604 				if(!xf86LoadSubModule(pScrn,"theatre200"))
   1605 				{
   1606 					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
   1607 					free(pPriv->theatre);
   1608 					goto skip_theatre;
   1609 				}
   1610 				pPriv->theatre->microc_path = info->RageTheatreMicrocPath;
   1611 				pPriv->theatre->microc_type = info->RageTheatreMicrocType;
   1612 				break;
   1613 			}
   1614 			default:
   1615 			{
   1616 				xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unknown Theatre chip\n");
   1617 				free(pPriv->theatre);
   1618 				goto skip_theatre;
   1619 			}
   1620 		}
   1621 	}
   1622 
   1623 	if(pPriv->theatre!=NULL)
   1624 	{
   1625 		xf86_InitTheatre(pPriv->theatre);
   1626 		if(pPriv->theatre->mode == MODE_UNINITIALIZED)
   1627 		{
   1628 			free(pPriv->theatre);
   1629 			pPriv->theatre = NULL;
   1630 			xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Rage Theatre disabled\n");
   1631 			/* Here the modules must be unloaded */
   1632 			goto skip_theatre;
   1633 		}
   1634 	}
   1635 
   1636     if(pPriv->theatre!=NULL){
   1637         xf86_ResetTheatreRegsForNoTVout(pPriv->theatre);
   1638         xf86_RT_SetTint(pPriv->theatre, pPriv->dec_hue);
   1639         xf86_RT_SetSaturation(pPriv->theatre, pPriv->dec_saturation);
   1640         xf86_RT_SetSharpness(pPriv->theatre, RT_NORM_SHARPNESS);
   1641         xf86_RT_SetContrast(pPriv->theatre, pPriv->dec_contrast);
   1642         xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
   1643 
   1644         RADEON_RT_SetEncoding(pScrn, pPriv);
   1645 	}
   1646 
   1647 skip_theatre:
   1648 
   1649     return adapt;
   1650 }
   1651 
   1652 static XF86VideoAdaptorPtr
   1653 RADEONSetupImageVideo(ScreenPtr pScreen)
   1654 {
   1655     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   1656     RADEONPortPrivPtr pPriv;
   1657     XF86VideoAdaptorPtr adapt;
   1658 
   1659     if(!(adapt = RADEONAllocAdaptor(pScrn)))
   1660 	return NULL;
   1661 
   1662     adapt->type = XvWindowMask | XvInputMask | XvImageMask;
   1663     adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
   1664     adapt->name = "ATI Radeon Video Overlay";
   1665     adapt->nEncodings = 1;
   1666     adapt->pEncodings = &DummyEncoding;
   1667     adapt->nFormats = NUM_FORMATS;
   1668     adapt->pFormats = Formats;
   1669     adapt->nPorts = 1;
   1670     adapt->nAttributes = NUM_ATTRIBUTES;
   1671     adapt->pAttributes = Attributes;
   1672     adapt->nImages = NUM_IMAGES;
   1673     adapt->pImages = Images;
   1674     adapt->PutVideo = NULL;
   1675     adapt->PutStill = NULL;
   1676     adapt->GetVideo = NULL;
   1677     adapt->GetStill = NULL;
   1678     adapt->StopVideo = RADEONStopVideo;
   1679     adapt->SetPortAttribute = RADEONSetPortAttribute;
   1680     adapt->GetPortAttribute = RADEONGetPortAttribute;
   1681     adapt->QueryBestSize = RADEONQueryBestSize;
   1682     adapt->PutImage = RADEONPutImage;
   1683     adapt->QueryImageAttributes = RADEONQueryImageAttributes;
   1684 
   1685     pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr);
   1686     REGION_NULL(pScreen, &(pPriv->clip));
   1687 
   1688     pPriv->textured = FALSE;
   1689 
   1690     if(pPriv->theatre != NULL) {
   1691 	/* video decoder is present, extend capabilities */
   1692        adapt->nEncodings = 13;
   1693        adapt->pEncodings = InputVideoEncodings;
   1694        adapt->type |= XvVideoMask;
   1695        adapt->nAttributes = NUM_DEC_ATTRIBUTES;
   1696        adapt->PutVideo = RADEONPutVideo;
   1697     }
   1698 
   1699     RADEONResetVideo(pScrn);
   1700 
   1701     return adapt;
   1702 }
   1703 
   1704 void
   1705 RADEONFreeVideoMemory(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
   1706 {
   1707     RADEONInfoPtr info = RADEONPTR(pScrn);
   1708 
   1709     if (pPriv->video_memory != NULL) {
   1710 	radeon_legacy_free_memory(pScrn, pPriv->video_memory);
   1711 	pPriv->video_memory = NULL;
   1712 
   1713 	if (info->cs && pPriv->textured) {
   1714 	    pPriv->src_bo[0] = NULL;
   1715 	    radeon_legacy_free_memory(pScrn, pPriv->src_bo[1]);
   1716 	    pPriv->src_bo[1] = NULL;
   1717 	}
   1718     }
   1719 }
   1720 
   1721 void
   1722 RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
   1723 {
   1724   RADEONInfoPtr info = RADEONPTR(pScrn);
   1725   unsigned char *RADEONMMIO = info->MMIO;
   1726   RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
   1727 
   1728   if (pPriv->textured) {
   1729       if (cleanup) {
   1730 	  RADEONFreeVideoMemory(pScrn, pPriv);
   1731       }
   1732       return;
   1733   }
   1734 
   1735   REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
   1736 
   1737   if(cleanup) {
   1738      if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
   1739 	RADEONWaitForFifo(pScrn, 2);
   1740 	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
   1741      }
   1742      if(pPriv->video_stream_active){
   1743         RADEONWaitForFifo(pScrn, 2);
   1744         OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
   1745         OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
   1746         RADEONResetVideo(pScrn);
   1747         pPriv->video_stream_active = FALSE;
   1748         if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
   1749 		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE);
   1750         if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
   1751      }
   1752      RADEONFreeVideoMemory(pScrn, pPriv);
   1753      pPriv->videoStatus = 0;
   1754   } else {
   1755      if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
   1756 	pPriv->videoStatus |= OFF_TIMER;
   1757 	pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
   1758      }
   1759   }
   1760 }
   1761 
   1762 int
   1763 RADEONSetPortAttribute(ScrnInfoPtr  pScrn,
   1764 		       Atom	    attribute,
   1765 		       INT32	    value,
   1766 		       pointer	    data)
   1767 {
   1768     RADEONInfoPtr	info = RADEONPTR(pScrn);
   1769     RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
   1770     Bool		setTransform = FALSE;
   1771     Bool		setAlpha = FALSE;
   1772     unsigned char *RADEONMMIO = info->MMIO;
   1773 
   1774     RADEON_SYNC(info, pScrn);
   1775 
   1776     if(attribute == xvAutopaintColorkey)
   1777     {
   1778 	pPriv->autopaint_colorkey = ClipValue (value, 0, 1);
   1779     }
   1780     else if(attribute == xvSetDefaults)
   1781     {
   1782 	pPriv->autopaint_colorkey = TRUE;
   1783 	pPriv->brightness = 0;
   1784 	pPriv->saturation = 0;
   1785 	pPriv->contrast = 0;
   1786 	pPriv->hue = 0;
   1787 	pPriv->red_intensity = 0;
   1788 	pPriv->green_intensity = 0;
   1789 	pPriv->blue_intensity = 0;
   1790 	pPriv->gamma = 1000;
   1791 	pPriv->transform_index = 0;
   1792 	pPriv->doubleBuffer = FALSE;
   1793 	pPriv->ov_alpha = 255;
   1794 	pPriv->gr_alpha = 255;
   1795 	pPriv->alpha_mode = 0;
   1796 
   1797         /* It is simpler to call itself */
   1798         RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data);
   1799         RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data);
   1800         RADEONSetPortAttribute(pScrn, xvDecContrast,   0, data);
   1801         RADEONSetPortAttribute(pScrn, xvDecHue,   0, data);
   1802 
   1803         RADEONSetPortAttribute(pScrn, xvVolume,   -1000, data);
   1804         RADEONSetPortAttribute(pScrn, xvMute,   1, data);
   1805         RADEONSetPortAttribute(pScrn, xvSAP,   0, data);
   1806         RADEONSetPortAttribute(pScrn, xvDoubleBuffer,   1, data);
   1807 
   1808 	setTransform = TRUE;
   1809 	setAlpha = TRUE;
   1810     }
   1811     else if(attribute == xvBrightness)
   1812     {
   1813 	pPriv->brightness = ClipValue (value, -1000, 1000);
   1814 	setTransform = TRUE;
   1815     }
   1816     else if((attribute == xvSaturation) || (attribute == xvColor))
   1817     {
   1818 	pPriv->saturation = ClipValue (value, -1000, 1000);
   1819 	setTransform = TRUE;
   1820     }
   1821     else if(attribute == xvContrast)
   1822     {
   1823 	pPriv->contrast = ClipValue (value, -1000, 1000);
   1824 	setTransform = TRUE;
   1825     }
   1826     else if(attribute == xvHue)
   1827     {
   1828 	pPriv->hue = ClipValue (value, -1000, 1000);
   1829 	setTransform = TRUE;
   1830     }
   1831     else if(attribute == xvRedIntensity)
   1832     {
   1833 	pPriv->red_intensity = ClipValue (value, -1000, 1000);
   1834 	setTransform = TRUE;
   1835     }
   1836     else if(attribute == xvGreenIntensity)
   1837     {
   1838 	pPriv->green_intensity = ClipValue (value, -1000, 1000);
   1839 	setTransform = TRUE;
   1840     }
   1841     else if(attribute == xvBlueIntensity)
   1842     {
   1843 	pPriv->blue_intensity = ClipValue (value, -1000, 1000);
   1844 	setTransform = TRUE;
   1845     }
   1846     else if(attribute == xvGamma)
   1847     {
   1848 	pPriv->gamma = ClipValue (value, 100, 10000);
   1849 	setTransform = TRUE;
   1850     }
   1851     else if(attribute == xvColorspace)
   1852     {
   1853 	pPriv->transform_index = ClipValue (value, 0, 1);
   1854 	setTransform = TRUE;
   1855     }
   1856     else if(attribute == xvDoubleBuffer)
   1857     {
   1858 	pPriv->doubleBuffer = ClipValue (value, 0, 1);
   1859     }
   1860     else if(attribute == xvColorKey)
   1861     {
   1862 	pPriv->colorKey = value;
   1863 	RADEONSetColorKey (pScrn, pPriv->colorKey);
   1864 	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
   1865     }
   1866     else if(attribute == xvCRTC)
   1867     {
   1868 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
   1869 	if ((value < -1) || (value > xf86_config->num_crtc))
   1870 	    return BadValue;
   1871 	if (value < 0)
   1872 	    pPriv->desired_crtc = NULL;
   1873 	else
   1874 	    pPriv->desired_crtc = xf86_config->crtc[value];
   1875     }
   1876     else if(attribute == xvOvAlpha)
   1877     {
   1878 	pPriv->ov_alpha = ClipValue (value, 0, 255);
   1879 	setAlpha = TRUE;
   1880     }
   1881     else if(attribute == xvGrAlpha)
   1882     {
   1883 	pPriv->gr_alpha = ClipValue (value, 0, 255);
   1884 	setAlpha = TRUE;
   1885     }
   1886     else if(attribute == xvAlphaMode)
   1887     {
   1888 	pPriv->alpha_mode = ClipValue (value, 0, 1);
   1889 	setAlpha = TRUE;
   1890     }
   1891     else if(attribute == xvDecBrightness)
   1892     {
   1893         pPriv->dec_brightness = value;
   1894         if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
   1895     }
   1896     else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
   1897     {
   1898         if(value<-1000)value = -1000;
   1899         if(value>1000)value = 1000;
   1900         pPriv->dec_saturation = value;
   1901         if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value);
   1902     }
   1903     else if(attribute == xvDecContrast)
   1904     {
   1905         pPriv->dec_contrast = value;
   1906         if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value);
   1907     }
   1908     else if(attribute == xvDecHue)
   1909     {
   1910         pPriv->dec_hue = value;
   1911         if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value);
   1912     }
   1913     else if(attribute == xvEncoding)
   1914     {
   1915         pPriv->encoding = value;
   1916         if(pPriv->video_stream_active)
   1917         {
   1918            if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);
   1919            if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
   1920            if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
   1921 	   if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
   1922            if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
   1923         /* put more here to actually change it */
   1924         }
   1925    }
   1926    else if(attribute == xvFrequency)
   1927    {
   1928         pPriv->frequency = value;
   1929         /* mute volume if it was not muted before */
   1930         if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
   1931 		if((pPriv->uda1380!=NULL)&& !pPriv->mute)xf86_uda1380_mute(pPriv->uda1380, TRUE);
   1932         if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value);
   1933 /*        if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);  */
   1934         if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck))
   1935                 xf86_InitMSP3430(pPriv->msp3430);
   1936         if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume));
   1937 		if((pPriv->uda1380 != NULL)&& !pPriv->mute) xf86_uda1380_setvolume(pPriv->uda1380, pPriv->volume);
   1938    }
   1939    else if(attribute == xvMute)
   1940    {
   1941         pPriv->mute = value;
   1942         if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
   1943         if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
   1944 		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, pPriv->mute);
   1945    }
   1946    else if(attribute == xvSAP)
   1947    {
   1948         pPriv->sap_channel = value;
   1949         if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3);
   1950    }
   1951    else if(attribute == xvVolume)
   1952    {
   1953         if(value<-1000)value = -1000;
   1954         if(value>1000)value = 1000;
   1955         pPriv->volume = value;
   1956         pPriv->mute = FALSE;
   1957         if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value));
   1958         if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
   1959 		if(pPriv->uda1380 != NULL) xf86_uda1380_setvolume(pPriv->uda1380, value);
   1960    }
   1961    else if(attribute == xvOverlayDeinterlacingMethod)
   1962    {
   1963         if(value<0)value = 0;
   1964         if(value>2)value = 2;
   1965         pPriv->overlay_deinterlacing_method = value;
   1966         switch(pPriv->overlay_deinterlacing_method){
   1967                 case METHOD_BOB:
   1968                         OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
   1969                         break;
   1970                 case METHOD_SINGLE:
   1971                         OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
   1972                         break;
   1973                 case METHOD_WEAVE:
   1974                         OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0);
   1975                         break;
   1976                 default:
   1977                         OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
   1978                 }
   1979    }
   1980    else if(attribute == xvDumpStatus)
   1981    {
   1982   	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n",
   1983 		pScrn->currentMode->Flags,
   1984 		pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" ,
   1985 		pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : ""
   1986 		);
   1987 	if(pPriv->tda9885 != NULL){
   1988 		xf86_tda9885_getstatus(pPriv->tda9885);
   1989 		xf86_tda9885_dumpstatus(pPriv->tda9885);
   1990 		}
   1991 	if(pPriv->fi1236!=NULL){
   1992 		xf86_fi1236_dump_status(pPriv->fi1236);
   1993 		}
   1994    }
   1995    else if(attribute == xvAdjustment)
   1996    {
   1997   	pPriv->adjustment=value;
   1998         xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n",
   1999 		   (unsigned)pPriv->adjustment);
   2000   	if(pPriv->tda9885!=0){
   2001 		pPriv->tda9885->top_adjustment=value;
   2002 		RADEON_TDA9885_SetEncoding(pPriv);
   2003 		}
   2004    }
   2005    else
   2006 	return BadMatch;
   2007 
   2008     if (setTransform)
   2009     {
   2010 	RADEONSetTransform(pScrn,
   2011 			   RTFBrightness(pPriv->brightness),
   2012 			   RTFContrast(pPriv->contrast),
   2013 			   RTFSaturation(pPriv->saturation),
   2014 			   RTFHue(pPriv->hue),
   2015 			   RTFIntensity(pPriv->red_intensity),
   2016 			   RTFIntensity(pPriv->green_intensity),
   2017 			   RTFIntensity(pPriv->blue_intensity),
   2018 			   pPriv->transform_index,
   2019 			   pPriv->gamma);
   2020     }
   2021 
   2022     if (setAlpha)
   2023     {
   2024 	RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode);
   2025     }
   2026 
   2027     return Success;
   2028 }
   2029 
   2030 int
   2031 RADEONGetPortAttribute(ScrnInfoPtr  pScrn,
   2032 		       Atom	    attribute,
   2033 		       INT32	    *value,
   2034 		       pointer	    data)
   2035 {
   2036     RADEONInfoPtr	info = RADEONPTR(pScrn);
   2037     RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
   2038 
   2039     if (info->accelOn) RADEON_SYNC(info, pScrn);
   2040 
   2041     if(attribute == xvAutopaintColorkey)
   2042 	*value = pPriv->autopaint_colorkey;
   2043     else if(attribute == xvBrightness)
   2044 	*value = pPriv->brightness;
   2045     else if((attribute == xvSaturation) || (attribute == xvColor))
   2046 	*value = pPriv->saturation;
   2047     else if(attribute == xvContrast)
   2048 	*value = pPriv->contrast;
   2049     else if(attribute == xvHue)
   2050 	*value = pPriv->hue;
   2051     else if(attribute == xvRedIntensity)
   2052 	*value = pPriv->red_intensity;
   2053     else if(attribute == xvGreenIntensity)
   2054 	*value = pPriv->green_intensity;
   2055     else if(attribute == xvBlueIntensity)
   2056 	*value = pPriv->blue_intensity;
   2057     else if(attribute == xvGamma)
   2058 	*value = pPriv->gamma;
   2059     else if(attribute == xvColorspace)
   2060 	*value = pPriv->transform_index;
   2061     else if(attribute == xvDoubleBuffer)
   2062 	*value = pPriv->doubleBuffer ? 1 : 0;
   2063     else if(attribute == xvColorKey)
   2064 	*value = pPriv->colorKey;
   2065     else if(attribute == xvCRTC) {
   2066 	int		c;
   2067 	xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
   2068 	for (c = 0; c < xf86_config->num_crtc; c++)
   2069 	    if (xf86_config->crtc[c] == pPriv->desired_crtc)
   2070 		break;
   2071 	if (c == xf86_config->num_crtc)
   2072 	    c = -1;
   2073 	*value = c;
   2074     }
   2075     else if(attribute == xvOvAlpha)
   2076 	*value = pPriv->ov_alpha;
   2077     else if(attribute == xvGrAlpha)
   2078 	*value = pPriv->gr_alpha;
   2079     else if(attribute == xvAlphaMode)
   2080 	*value = pPriv->alpha_mode;
   2081     else if(attribute == xvDecBrightness)
   2082         *value = pPriv->dec_brightness;
   2083     else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
   2084         *value = pPriv->dec_saturation;
   2085     else if(attribute == xvDecContrast)
   2086         *value = pPriv->dec_contrast;
   2087     else if(attribute == xvDecHue)
   2088         *value = pPriv->dec_hue;
   2089     else if(attribute == xvEncoding)
   2090         *value = pPriv->encoding;
   2091     else if(attribute == xvFrequency)
   2092         *value = pPriv->frequency;
   2093     else
   2094     if(attribute == xvTunerStatus) {
   2095         if(pPriv->fi1236==NULL){
   2096                 *value=TUNER_OFF;
   2097                 } else
   2098                 {
   2099                 *value = xf86_TUNER_get_afc_hint(pPriv->fi1236);
   2100                 }
   2101        }
   2102     else if(attribute == xvMute)
   2103         *value = pPriv->mute;
   2104     else if(attribute == xvSAP)
   2105         *value = pPriv->sap_channel;
   2106     else if(attribute == xvVolume)
   2107         *value = pPriv->volume;
   2108     else if(attribute == xvOverlayDeinterlacingMethod)
   2109         *value = pPriv->overlay_deinterlacing_method;
   2110     else if(attribute == xvDeviceID)
   2111         *value = pPriv->device_id;
   2112     else if(attribute == xvLocationID)
   2113         *value = pPriv->location_id;
   2114     else if(attribute == xvInstanceID)
   2115         *value = pPriv->instance_id;
   2116     else if(attribute == xvAdjustment)
   2117   	*value = pPriv->adjustment;
   2118     else
   2119 	return BadMatch;
   2120 
   2121     return Success;
   2122 }
   2123 
   2124 void
   2125 RADEONQueryBestSize(
   2126   ScrnInfoPtr pScrn,
   2127   Bool motion,
   2128   short vid_w, short vid_h,
   2129   short drw_w, short drw_h,
   2130   unsigned int *p_w, unsigned int *p_h,
   2131   pointer data
   2132 ){
   2133     RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
   2134 
   2135     if (!pPriv->textured) {
   2136 	if (vid_w > (drw_w << 4))
   2137 	    drw_w = vid_w >> 4;
   2138 	if (vid_h > (drw_h << 4))
   2139 	    drw_h = vid_h >> 4;
   2140     }
   2141 
   2142   *p_w = drw_w;
   2143   *p_h = drw_h;
   2144 }
   2145 
   2146 static struct {
   2147 	double range;
   2148 	signed char coeff[5][4];
   2149 	} TapCoeffs[]=
   2150 	{
   2151         {0.25, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13,   13,    3}, }},
   2152         {0.26, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2153         {0.27, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2154         {0.28, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2155         {0.29, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2156         {0.30, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2157         {0.31, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2158         {0.32, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2159         {0.33, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2160         {0.34, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2161         {0.35, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2162         {0.36, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2163         {0.37, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2164         {0.38, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2165         {0.39, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2166         {0.40, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2167         {0.41, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2168         {0.42, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2169         {0.43, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2170         {0.44, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2171         {0.45, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2172         {0.46, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2173         {0.47, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2174         {0.48, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2175         {0.49, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2176         {0.50, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
   2177         {0.51, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 2,   14, 14,  2}, }},
   2178         {0.52, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
   2179         {0.53, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
   2180         {0.54, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
   2181         {0.55, {{ 7,    18,  7,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 1,   15, 15,  1}, }},
   2182         {0.56, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2183         {0.57, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2184         {0.58, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2185         {0.59, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2186         {0.60, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2187         {0.61, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2188         {0.62, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2189         {0.63, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2190         {0.64, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
   2191         {0.65, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
   2192         {0.66, {{ 7,    18,  8, -1}, { 6,   18, 10, -2}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
   2193         {0.67, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   18, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
   2194         {0.68, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
   2195         {0.69, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
   2196         {0.70, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
   2197         {0.71, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
   2198         {0.72, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
   2199         {0.73, {{ 7,    20,  7, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
   2200         {0.74, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
   2201         {0.75, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
   2202         {0.76, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
   2203         {0.77, {{ 6,    22,  6, -2}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
   2204         {0.78, {{ 6,    21,  6, -1}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
   2205         {0.79, {{ 5,    23,  5, -1}, { 3,   22,  9, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
   2206         {0.80, {{ 5,    23,  5, -1}, { 3,   23,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
   2207         {0.81, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
   2208         {0.82, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-3,   19, 19, -3}, }},
   2209         {0.83, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
   2210         {0.84, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
   2211         {0.85, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
   2212         {0.86, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
   2213         {0.87, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
   2214         {0.88, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
   2215         {0.89, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
   2216         {0.90, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
   2217         {0.91, {{ 3,    26,  3,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
   2218         {0.92, {{ 2,    28,  2,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
   2219         {0.93, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
   2220         {0.94, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
   2221         {0.95, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
   2222         {0.96, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
   2223         {0.97, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
   2224         {0.98, {{ 1,    30,  1,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
   2225         {0.99, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }},
   2226         {1.00, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }}
   2227     };
   2228 
   2229 void
   2230 RADEONCopyData(
   2231   ScrnInfoPtr pScrn,
   2232   unsigned char *src,
   2233   unsigned char *dst,
   2234   unsigned int srcPitch,
   2235   unsigned int dstPitch,
   2236   unsigned int h,
   2237   unsigned int w,
   2238   unsigned int bpp
   2239 ){
   2240     RADEONInfoPtr info = RADEONPTR(pScrn);
   2241 
   2242     /* Get the byte-swapping right for big endian systems */
   2243     if ( bpp == 2 ) {
   2244 	w *= 2;
   2245 	bpp = 1;
   2246     }
   2247 
   2248 #ifdef XF86DRI
   2249 
   2250     if ( info->directRenderingEnabled && info->DMAForXv )
   2251     {
   2252 	uint8_t *buf;
   2253 	uint32_t bufPitch, dstPitchOff;
   2254 	int x, y;
   2255 	unsigned int hpass;
   2256 
   2257 	RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y );
   2258 
   2259 	while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch,
   2260 					   x, &y, &h, &hpass )) )
   2261 	{
   2262 	    RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch,
   2263 					srcPitch );
   2264 	    src += hpass * srcPitch;
   2265 	}
   2266 
   2267 	FLUSH_RING();
   2268 
   2269 	return;
   2270     }
   2271     else
   2272 #endif /* XF86DRI */
   2273     {
   2274 	int swap = RADEON_HOST_DATA_SWAP_NONE;
   2275 
   2276 #if X_BYTE_ORDER == X_BIG_ENDIAN
   2277 	if (info->kms_enabled) {
   2278 	    switch(bpp) {
   2279 	    case 2:
   2280 		swap = RADEON_HOST_DATA_SWAP_16BIT;
   2281 		break;
   2282 	    case 4:
   2283 		swap = RADEON_HOST_DATA_SWAP_32BIT;
   2284 		break;
   2285 	    }
   2286 	} else {
   2287 	    switch (pScrn->bitsPerPixel) {
   2288 	    case 16:
   2289 		swap = RADEON_HOST_DATA_SWAP_16BIT;
   2290 		break;
   2291 	    case 32:
   2292 		swap = RADEON_HOST_DATA_SWAP_32BIT;
   2293 		break;
   2294 	    }
   2295 	}
   2296 #endif
   2297 
   2298 	w *= bpp;
   2299 
   2300 	if (dstPitch == w && dstPitch == srcPitch)
   2301 	    RADEONCopySwap(dst, src, h * dstPitch, swap);
   2302 	else {
   2303 	    while (h--) {
   2304 		RADEONCopySwap(dst, src, w, swap);
   2305 		src += srcPitch;
   2306 		dst += dstPitch;
   2307 	    }
   2308 	}
   2309     }
   2310 }
   2311 
   2312 static void
   2313 RADEONCopyRGB24Data(
   2314   ScrnInfoPtr pScrn,
   2315   unsigned char *src,
   2316   unsigned char *dst,
   2317   unsigned int srcPitch,
   2318   unsigned int dstPitch,
   2319   unsigned int h,
   2320   unsigned int w
   2321 ){
   2322     uint32_t *dptr;
   2323     uint8_t *sptr;
   2324     int i,j;
   2325     RADEONInfoPtr info = RADEONPTR(pScrn);
   2326 #ifdef XF86DRI
   2327 
   2328     if ( info->directRenderingEnabled && info->DMAForXv )
   2329     {
   2330 	uint32_t bufPitch, dstPitchOff;
   2331 	int x, y;
   2332 	unsigned int hpass;
   2333 
   2334 	RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y );
   2335 
   2336 	while ( (dptr = ( uint32_t* )RADEONHostDataBlit( pScrn, 4, w, dstPitchOff,
   2337 						       &bufPitch, x, &y, &h,
   2338 						       &hpass )) )
   2339 	{
   2340 	    for( j = 0; j < hpass; j++ )
   2341 	    {
   2342 		sptr = src;
   2343 
   2344 		for ( i = 0 ; i < w; i++, sptr += 3 )
   2345 		{
   2346 		    dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0];
   2347 		}
   2348 
   2349 		src += srcPitch;
   2350 		dptr += bufPitch / 4;
   2351 	    }
   2352 	}
   2353 
   2354 	FLUSH_RING();
   2355 
   2356 	return;
   2357     }
   2358     else
   2359 #endif /* XF86DRI */
   2360     {
   2361 #if X_BYTE_ORDER == X_BIG_ENDIAN
   2362 	unsigned char *RADEONMMIO = info->MMIO;
   2363 
   2364 	if (!info->kms_enabled)
   2365 	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
   2366 		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
   2367 #endif
   2368 
   2369 	for (j = 0; j < h; j++) {
   2370 	    dptr = (uint32_t *)(dst + j * dstPitch);
   2371 	    sptr = src + j * srcPitch;
   2372 
   2373 	    for (i = 0; i < w; i++, sptr += 3) {
   2374 		dptr[i] = cpu_to_le32((sptr[2] << 16) | (sptr[1] << 8) | sptr[0]);
   2375 	    }
   2376 	}
   2377 
   2378 #if X_BYTE_ORDER == X_BIG_ENDIAN
   2379 	if (!info->kms_enabled) {
   2380 	    /* restore byte swapping */
   2381 	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
   2382 	}
   2383 #endif
   2384     }
   2385 }
   2386 
   2387 
   2388 #ifdef XF86DRI
   2389 static void RADEON_420_422(
   2390     unsigned int *d,
   2391     unsigned char *s1,
   2392     unsigned char *s2,
   2393     unsigned char *s3,
   2394     unsigned int n
   2395 )
   2396 {
   2397     while ( n ) {
   2398 	*(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
   2399 	s1+=2; s2++; s3++;
   2400 	n--;
   2401     }
   2402 }
   2403 #endif
   2404 
   2405 void
   2406 RADEONCopyMungedData(
   2407    ScrnInfoPtr pScrn,
   2408    unsigned char *src1,
   2409    unsigned char *src2,
   2410    unsigned char *src3,
   2411    unsigned char *dst1,
   2412    unsigned int srcPitch,
   2413    unsigned int srcPitch2,
   2414    unsigned int dstPitch,
   2415    unsigned int h,
   2416    unsigned int w
   2417 ){
   2418     RADEONInfoPtr info = RADEONPTR(pScrn);
   2419 #ifdef XF86DRI
   2420 
   2421     if ( info->directRenderingEnabled && info->DMAForXv )
   2422     {
   2423 	uint8_t *buf;
   2424 	uint32_t y = 0, bufPitch, dstPitchOff;
   2425 	int blitX, blitY;
   2426 	unsigned int hpass;
   2427 
   2428 	/* XXX Fix endian flip on R300 */
   2429 
   2430 	RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY );
   2431 
   2432 	while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch,
   2433 					   blitX, &blitY, &h, &hpass )) )
   2434 	{
   2435 	    while ( hpass-- )
   2436 	    {
   2437 		RADEON_420_422( (unsigned int *) buf, src1, src2, src3,
   2438 				bufPitch / 4 );
   2439 		src1 += srcPitch;
   2440 		if ( y & 1 )
   2441 		{
   2442 		    src2 += srcPitch2;
   2443 		    src3 += srcPitch2;
   2444 		}
   2445 		buf += bufPitch;
   2446 		y++;
   2447 	    }
   2448 	}
   2449 
   2450 	FLUSH_RING();
   2451     }
   2452     else
   2453 #endif /* XF86DRI */
   2454     {
   2455 	uint32_t *dst;
   2456 	uint8_t *s1, *s2, *s3;
   2457 	int i, j;
   2458 
   2459 #if X_BYTE_ORDER == X_BIG_ENDIAN
   2460 	unsigned char *RADEONMMIO = info->MMIO;
   2461 
   2462 	if (!info->kms_enabled)
   2463 	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
   2464 		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
   2465 #endif
   2466 
   2467 	w /= 2;
   2468 
   2469 	for( j = 0; j < h; j++ )
   2470 	{
   2471 	    dst = (pointer)dst1;
   2472 	    s1 = src1;  s2 = src2;  s3 = src3;
   2473 	    i = w;
   2474 	    while( i > 4 )
   2475 	    {
   2476 		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
   2477 		dst[1] = cpu_to_le32(s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24));
   2478 		dst[2] = cpu_to_le32(s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24));
   2479 		dst[3] = cpu_to_le32(s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24));
   2480 		dst += 4; s2 += 4; s3 += 4; s1 += 8;
   2481 		i -= 4;
   2482 	    }
   2483 	    while( i-- )
   2484 	    {
   2485 		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
   2486 		dst++; s2++; s3++;
   2487 		s1 += 2;
   2488 	    }
   2489 
   2490 	    dst1 += dstPitch;
   2491 	    src1 += srcPitch;
   2492 	    if( j & 1 )
   2493 	    {
   2494 		src2 += srcPitch2;
   2495 		src3 += srcPitch2;
   2496 	    }
   2497 	}
   2498 #if X_BYTE_ORDER == X_BIG_ENDIAN
   2499 	if (!info->kms_enabled) {
   2500 	    /* restore byte swapping */
   2501 	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
   2502 	}
   2503 #endif
   2504     }
   2505 }
   2506 
   2507 static void
   2508 RADEONDisplayVideo(
   2509     ScrnInfoPtr pScrn,
   2510     xf86CrtcPtr crtc,
   2511     RADEONPortPrivPtr pPriv,
   2512     int id,
   2513     int base_offset,
   2514     int offset1, int offset2,
   2515     int offset3, int offset4,
   2516     int offset5, int offset6,
   2517     short width, short height,
   2518     int pitch,
   2519     int left, int right, int top,
   2520     BoxPtr dstBox,
   2521     short src_w, short src_h,
   2522     short drw_w, short drw_h,
   2523     int deinterlacing_method
   2524 ){
   2525     RADEONInfoPtr info = RADEONPTR(pScrn);
   2526     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
   2527     unsigned char *RADEONMMIO = info->MMIO;
   2528     uint32_t v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp;
   2529     double h_inc_d;
   2530     int p1_h_accum_init, p23_h_accum_init;
   2531     int p1_v_accum_init, p23_v_accum_init;
   2532     int p23_blank_lines;
   2533     int ecp_div;
   2534     int v_inc_shift;
   2535     int y_mult;
   2536     int x_off;
   2537     int y_off;
   2538     uint32_t scaler_src;
   2539     uint32_t dot_clock;
   2540     int is_rgb;
   2541     int is_planar;
   2542     int i;
   2543     uint32_t scale_cntl;
   2544     double dsr;
   2545     int tap_set;
   2546     int predownscale=0;
   2547     int src_w_d;
   2548     int leftuv = 0;
   2549     DisplayModePtr mode;
   2550     RADEONOutputPrivatePtr radeon_output;
   2551     xf86OutputPtr output;
   2552     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
   2553 
   2554     is_rgb=0; is_planar=0;
   2555     switch(id){
   2556         case FOURCC_I420:
   2557         case FOURCC_YV12:
   2558             is_planar=1;
   2559             break;
   2560         case FOURCC_RGBA32:
   2561         case FOURCC_RGB24:
   2562         case FOURCC_RGBT16:
   2563         case FOURCC_RGB16:
   2564             is_rgb=1;
   2565             break;
   2566         default:
   2567 	    break;
   2568     }
   2569 
   2570     /* Here we need to find ecp_div again, as the user may have switched resolutions
   2571        but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to
   2572        workarounds for chip erratas */
   2573 
   2574     /* Figure out which head we are on for dot clock */
   2575     if (radeon_crtc->crtc_id == 1)
   2576         dot_clock = info->ModeReg->dot_clock_freq_2;
   2577     else
   2578         dot_clock = info->ModeReg->dot_clock_freq;
   2579 
   2580     if (dot_clock < 17500)
   2581         ecp_div = 0;
   2582     else
   2583 	ecp_div = 1;
   2584 
   2585     if (ecp_div != info->ecp_div) {
   2586 	info->ecp_div = ecp_div;
   2587 	OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
   2588 	   (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
   2589     }
   2590 
   2591     /* I suspect we may need a usleep after writing to the PLL.  if you play a video too soon
   2592        after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
   2593        on the right edge video output.
   2594        Is this still the case? Might have been chips which need the errata,
   2595        there is now plenty of usleep after INPLL/OUTPLL for those...*/
   2596 
   2597     v_inc_shift = 20;
   2598     y_mult = 1;
   2599 
   2600     mode = &crtc->mode;
   2601 
   2602     if (mode->Flags & V_INTERLACE)
   2603 	v_inc_shift++;
   2604     if (mode->Flags & V_DBLSCAN) {
   2605 	v_inc_shift--;
   2606 	y_mult = 2;
   2607     }
   2608 
   2609     v_inc = (src_h << v_inc_shift) / drw_h;
   2610 
   2611     for (i = 0; i < xf86_config->num_output; i++) {
   2612 	output = xf86_config->output[i];
   2613 	if (output->crtc == crtc) {
   2614 	    radeon_output = output->driver_private;
   2615 	    if (radeon_output->Flags & RADEON_USE_RMX)
   2616 		v_inc = ((src_h * mode->CrtcVDisplay /
   2617 			  radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h;
   2618 	    break;
   2619 	}
   2620     }
   2621 
   2622     h_inc = (1 << (12 + ecp_div));
   2623 
   2624     step_by_y = 1;
   2625     step_by_uv = step_by_y;
   2626 
   2627     src_w_d = src_w;
   2628 #if 0
   2629     /* XXX this does not appear to work */
   2630     /* if the source width was larger than what would fit in overlay scaler increase step_by values */
   2631     i=src_w;
   2632     while(i>info->overlay_scaler_buffer_width){
   2633 	step_by_y++;
   2634 	step_by_uv++;
   2635 	h_inc >>=1;
   2636 	i=i/2;
   2637 	}
   2638 #else
   2639     /* predownscale instead (yes this hurts quality) - will only work for widths up
   2640        to 2 times the overlay_scaler_buffer_width, should be enough */
   2641     if (src_w_d > info->overlay_scaler_buffer_width) {
   2642 	src_w_d /= 2; /* odd widths? */
   2643 	predownscale = 1;
   2644     }
   2645 #endif
   2646 
   2647     h_inc_d = src_w_d;
   2648     h_inc_d = h_inc_d/drw_w;
   2649     /* we could do a tad better  - but why
   2650        bother when this concerns downscaling and the code is so much more
   2651        hairy */
   2652     while(h_inc*h_inc_d >= (2 << 12)) {
   2653         if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){
   2654                 step_by_uv = step_by_y+1;
   2655                 break;
   2656                 }
   2657         step_by_y++;
   2658         step_by_uv = step_by_y;
   2659         h_inc >>= 1;
   2660     }
   2661 
   2662     h_inc_uv = h_inc>>(step_by_uv-step_by_y);
   2663     h_inc = h_inc * h_inc_d;
   2664     h_inc_uv = h_inc_uv * h_inc_d;
   2665     /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit
   2666        in the buffer for 2 tap filtering */
   2667     /* the only place it is documented in is in ATI source code */
   2668     /* we need twice as much space for 4 tap filtering.. */
   2669     /* under special circumstances turn on 4 tap filtering */
   2670     /* disable this code for now as it has a DISASTROUS effect on image quality when upscaling
   2671        at least on rv250 (only as long as the drw_w*2 <=... requirement is still met of course) */
   2672 #if 0
   2673     if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12))
   2674        && (deinterlacing_method!=METHOD_WEAVE)
   2675        && (drw_w*2 <= info->overlay_scaler_buffer_width)){
   2676         step_by_y=0;
   2677         step_by_uv=1;
   2678         h_inc_uv = h_inc;
   2679         }
   2680 #endif
   2681 
   2682     /* Make the overlay base address as close to the buffers as possible to
   2683      * prevent the buffer offsets from exceeding the hardware limit of 128 MB.
   2684      * The base address must be aligned to a multiple of 4 MB.
   2685      */
   2686     base_offset = ((info->fbLocation + base_offset) & (~0U << 22)) -
   2687 	info->fbLocation;
   2688 
   2689     offset1 -= base_offset;
   2690     offset2 -= base_offset;
   2691     offset3 -= base_offset;
   2692     offset4 -= base_offset;
   2693     offset5 -= base_offset;
   2694     offset6 -= base_offset;
   2695 
   2696     /* keep everything in 16.16 */
   2697 
   2698     if (is_planar) {
   2699 	offset1 += ((left >> 16) & ~15);
   2700 	offset2 += ((left >> 16) & ~31) >> 1;
   2701 	offset3 += ((left >> 16) & ~31) >> 1;
   2702 	offset4 += ((left >> 16) & ~15);
   2703 	offset5 += ((left >> 16) & ~31) >> 1;
   2704 	offset6 += ((left >> 16) & ~31) >> 1;
   2705 	offset2 |= RADEON_VIF_BUF0_PITCH_SEL;
   2706 	offset3 |= RADEON_VIF_BUF0_PITCH_SEL;
   2707 	offset5 |= RADEON_VIF_BUF0_PITCH_SEL;
   2708 	offset6 |= RADEON_VIF_BUF0_PITCH_SEL;
   2709     }
   2710     else {
   2711 	/* is this really correct for non-2-byte formats? */
   2712 	offset1 += ((left >> 16) & ~7) << 1;
   2713 	offset2 += ((left >> 16) & ~7) << 1;
   2714 	offset3 += ((left >> 16) & ~7) << 1;
   2715 	offset4 += ((left >> 16) & ~7) << 1;
   2716 	offset5 += ((left >> 16) & ~7) << 1;
   2717 	offset6 += ((left >> 16) & ~7) << 1;
   2718     }
   2719 
   2720     tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
   2721     p1_h_accum_init = ((tmp <<  4) & 0x000f8000) |
   2722 		      ((tmp << 12) & 0xf0000000);
   2723 
   2724     tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2);
   2725     p23_h_accum_init = ((tmp <<  4) & 0x000f8000) |
   2726 		       ((tmp << 12) & 0x70000000);
   2727 
   2728     tmp = (top & 0x0000ffff) + 0x00018000;
   2729     p1_v_accum_init = ((tmp << 4) & 0x03ff8000) |
   2730     	(((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01);
   2731 
   2732     if (is_planar) {
   2733 	p23_v_accum_init = ((tmp << 4) & 0x03ff8000) |
   2734 	    ((deinterlacing_method != METHOD_WEAVE) ? 0x03 : 0x01);
   2735 	p23_blank_lines = (((src_h >> 1) - 1) << 16);
   2736     }
   2737     else {
   2738 	p23_v_accum_init = 0;
   2739 	p23_blank_lines = 0;
   2740     }
   2741 
   2742     if (is_planar) {
   2743 	leftuv = ((left >> 16) >> 1) & 15;
   2744 	left = (left >> 16) & 15;
   2745     }
   2746     else {
   2747 	left = (left >> 16) & 7;
   2748 	if (!is_rgb)
   2749 	    leftuv = left >> 1;
   2750     }
   2751 
   2752     RADEONWaitForFifo(pScrn, 2);
   2753     OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK);
   2754     if (info->accelOn) RADEON_SYNC(info, pScrn);
   2755     while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
   2756 
   2757     RADEONWaitForFifo(pScrn, 10);
   2758     OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16));
   2759     OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) |
   2760 	predownscale << 4 | predownscale << 12);
   2761 
   2762     x_off = 8;
   2763     y_off = 0;
   2764 
   2765     if (IS_R300_VARIANT ||
   2766         (info->ChipFamily == CHIP_FAMILY_R200))
   2767 	x_off = 0;
   2768 
   2769     /* needed to make the overlay work on crtc1 in leftof and above modes */
   2770     /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */
   2771     /*
   2772     if (srel == radeonLeftOf) {
   2773 	x_off -= mode->CrtcHDisplay;
   2774     }
   2775     if (srel == radeonAbove) {
   2776 	y_off -= mode->CrtcVDisplay;
   2777     }
   2778     */
   2779 
   2780     /* Put the hardware overlay on CRTC2:
   2781      *
   2782      * Since one hardware overlay can not be displayed on two heads
   2783      * at the same time, we might need to consider using software
   2784      * rendering for the second head.
   2785      */
   2786 
   2787     if (radeon_crtc->crtc_id == 1) {
   2788         x_off = 0;
   2789         OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
   2790                                       ((dstBox->y1*y_mult) << 16)));
   2791         OUTREG(RADEON_OV1_Y_X_END,   ((dstBox->x2 + x_off) |
   2792                                       ((dstBox->y2*y_mult) << 16)));
   2793         scaler_src = RADEON_SCALER_CRTC_SEL;
   2794     } else {
   2795 	OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) |
   2796 				      (((dstBox->y1*y_mult) + y_off) << 16)));
   2797 	OUTREG(RADEON_OV0_Y_X_END,   ((dstBox->x2 + x_off) |
   2798 				      (((dstBox->y2*y_mult) + y_off) << 16)));
   2799 	scaler_src = 0;
   2800     }
   2801 
   2802     /* program the tap coefficients for better downscaling quality.
   2803        Could do slightly better by using hardcoded coefficients for one axis
   2804        in case only the other axis is downscaled (see RADEON_OV0_FILTER_CNTL) */
   2805     dsr=(double)(1<<0xC)/h_inc;
   2806     if(dsr<0.25)dsr=0.25;
   2807     if(dsr>1.0)dsr=1.0;
   2808     tap_set=(int)((dsr-0.25)*100);
   2809     for(i=0;i<5;i++){
   2810 	    OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) |
   2811 	    	((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) |
   2812 	    	((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) |
   2813 	    	((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24));
   2814 		}
   2815 
   2816     RADEONWaitForFifo(pScrn, 11);
   2817     OUTREG(RADEON_OV0_V_INC, v_inc);
   2818     OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));
   2819     OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | p23_blank_lines);
   2820     OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch);
   2821     OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch);
   2822     OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16));
   2823     if (!is_rgb)
   2824 	src_w >>= 1;
   2825     OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
   2826     OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
   2827     if (info->ModeReg->ov0_base_addr != (info->fbLocation + base_offset)) {
   2828 	ErrorF("Changing OV0_BASE_ADDR from 0x%08x to 0x%08x\n",
   2829 	       info->ModeReg->ov0_base_addr, (uint32_t)info->fbLocation + base_offset);
   2830 	info->ModeReg->ov0_base_addr = info->fbLocation + base_offset;
   2831 	OUTREG(RADEON_OV0_BASE_ADDR, info->ModeReg->ov0_base_addr);
   2832     }
   2833     OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1);
   2834     OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2);
   2835     OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3);
   2836 
   2837     RADEONWaitForFifo(pScrn, 9);
   2838     OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4);
   2839     OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset5);
   2840     OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset6);
   2841     OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
   2842     OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
   2843     OUTREG(RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init);
   2844     OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
   2845 
   2846    scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER
   2847         | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16) | scaler_src;
   2848    switch(id){
   2849         case FOURCC_UYVY:
   2850 		scale_cntl |= RADEON_SCALER_SOURCE_YVYU422;
   2851 		break;
   2852         case FOURCC_RGB24:
   2853         case FOURCC_RGBA32:
   2854 		scale_cntl |= RADEON_SCALER_SOURCE_32BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
   2855 		break;
   2856         case FOURCC_RGB16:
   2857 		scale_cntl |= RADEON_SCALER_SOURCE_16BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
   2858 		break;
   2859         case FOURCC_RGBT16:
   2860 		scale_cntl |= RADEON_SCALER_SOURCE_15BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
   2861 		break;
   2862         case FOURCC_YV12:
   2863         case FOURCC_I420:
   2864 		scale_cntl |= RADEON_SCALER_SOURCE_YUV12;
   2865 		break;
   2866         case FOURCC_YUY2:
   2867         default:
   2868 		scale_cntl |= RADEON_SCALER_SOURCE_VYUY422
   2869 			| ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0);
   2870 		break;
   2871     }
   2872 
   2873     if (info->ChipFamily < CHIP_FAMILY_R200) {
   2874 	scale_cntl &= ~RADEON_SCALER_GAMMA_SEL_MASK;
   2875 	scale_cntl |= ((RADEONTranslateUserGamma(pPriv->gamma)) << 5);
   2876     }
   2877 
   2878     OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl);
   2879     OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
   2880 }
   2881 
   2882 
   2883 static void
   2884 RADEONFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes)
   2885 {
   2886 #if HAVE_XV_DRAWABLE_HELPER
   2887     xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes);
   2888 #else
   2889     xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes);
   2890 #endif
   2891 }
   2892 
   2893 
   2894 static int
   2895 RADEONPutImage(
   2896   ScrnInfoPtr pScrn,
   2897   short src_x, short src_y,
   2898   short drw_x, short drw_y,
   2899   short src_w, short src_h,
   2900   short drw_w, short drw_h,
   2901   int id, unsigned char* buf,
   2902   short width, short height,
   2903   Bool Sync,
   2904   RegionPtr clipBoxes, pointer data,
   2905   DrawablePtr pDraw
   2906 ){
   2907    RADEONInfoPtr info = RADEONPTR(pScrn);
   2908    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
   2909    INT32 xa, xb, ya, yb;
   2910    unsigned char *dst_start;
   2911    int new_size, offset, s2offset, s3offset;
   2912    int srcPitch, srcPitch2, dstPitch;
   2913    int d2line, d3line;
   2914    int top, left, npixels, nlines, bpp;
   2915    int idconv = id;
   2916    BoxRec dstBox;
   2917    uint32_t tmp;
   2918    xf86CrtcPtr crtc;
   2919 
   2920    /*
   2921     * s2offset, s3offset - byte offsets into U and V plane of the
   2922     *                      source where copying starts.  Y plane is
   2923     *                      done by editing "buf".
   2924     *
   2925     * offset - byte offset to the first line of the destination.
   2926     *
   2927     * dst_start - byte address to the first displayed pel.
   2928     *
   2929     */
   2930 
   2931    /* make the compiler happy */
   2932    s2offset = s3offset = srcPitch2 = 0;
   2933    d2line = d3line = 0;
   2934 
   2935    if(src_w > (drw_w << 4))
   2936 	drw_w = src_w >> 4;
   2937    if(src_h > (drw_h << 4))
   2938 	drw_h = src_h >> 4;
   2939 
   2940    /* Clip */
   2941    xa = src_x;
   2942    xb = src_x + src_w;
   2943    ya = src_y;
   2944    yb = src_y + src_h;
   2945 
   2946    dstBox.x1 = drw_x;
   2947    dstBox.x2 = drw_x + drw_w;
   2948    dstBox.y1 = drw_y;
   2949    dstBox.y2 = drw_y + drw_h;
   2950 
   2951    if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
   2952 			       &dstBox, &xa, &xb, &ya, &yb,
   2953 			       clipBoxes, width, height))
   2954        return Success;
   2955 
   2956    if (!crtc) {
   2957        if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
   2958 	   unsigned char *RADEONMMIO = info->MMIO;
   2959 	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
   2960 	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
   2961        }
   2962        return Success;
   2963    }
   2964 
   2965    dstBox.x1 -= crtc->x;
   2966    dstBox.x2 -= crtc->x;
   2967    dstBox.y1 -= crtc->y;
   2968    dstBox.y2 -= crtc->y;
   2969 
   2970    bpp = pScrn->bitsPerPixel >> 3;
   2971 
   2972    switch(id) {
   2973    case FOURCC_RGB24:
   2974 	dstPitch = width * 4;
   2975 	srcPitch = width * 3;
   2976 	break;
   2977    case FOURCC_RGBA32:
   2978 	dstPitch = width * 4;
   2979 	srcPitch = width * 4;
   2980 	break;
   2981    case FOURCC_RGB16:
   2982    case FOURCC_RGBT16:
   2983 	dstPitch = width * 2;
   2984 	srcPitch = RADEON_ALIGN(width * 2, 4);
   2985 	break;
   2986    case FOURCC_YV12:
   2987    case FOURCC_I420:
   2988 	/* it seems rs4xx chips (all of them???) either can't handle planar
   2989 	   yuv at all or would need some unknown different setup. */
   2990        if ((info->ChipFamily != CHIP_FAMILY_RS400) &&
   2991 	   (info->ChipFamily != CHIP_FAMILY_RS480)) {
   2992 	    /* need 16bytes alignment for u,v plane, so 2 times that for width
   2993 	       but blitter needs 64bytes alignment. 128byte is a waste but dstpitch
   2994 	       for uv planes needs to be dstpitch yplane >> 1 for now. */
   2995 	    dstPitch = (RADEON_ALIGN(width, 128));
   2996 	    srcPitch = RADEON_ALIGN(width, 4);
   2997 	}
   2998 	else {
   2999 	    dstPitch = width * 2;
   3000 	    srcPitch = RADEON_ALIGN(width, 4);
   3001 	    idconv = FOURCC_YUY2;
   3002 	}
   3003 	break;
   3004    case FOURCC_UYVY:
   3005    case FOURCC_YUY2:
   3006    default:
   3007 	dstPitch = width * 2;
   3008 	srcPitch = width * 2;
   3009 	break;
   3010    }
   3011 
   3012 #ifdef XF86DRI
   3013    if (info->directRenderingEnabled && info->DMAForXv) {
   3014        /* The upload blit only supports multiples of 64 bytes */
   3015        dstPitch = RADEON_ALIGN(dstPitch, 64);
   3016    } else
   3017 #endif
   3018        /* The overlay only supports multiples of 16 bytes */
   3019        dstPitch = RADEON_ALIGN(dstPitch, 16);
   3020 
   3021    new_size = dstPitch * height;
   3022    if (idconv == FOURCC_YV12 || id == FOURCC_I420) {
   3023       new_size += (dstPitch >> 1) * (RADEON_ALIGN(height, 2));
   3024    }
   3025    pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
   3026 						       (pPriv->doubleBuffer ?
   3027 						       (new_size * 2) : new_size), 64,
   3028 						       RADEON_GEM_DOMAIN_VRAM);
   3029    if (pPriv->video_offset == 0)
   3030       return BadAlloc;
   3031 
   3032    pPriv->currentBuffer ^= 1;
   3033 
   3034     /* copy data */
   3035    top = ya >> 16;
   3036    left = (xa >> 16) & ~1;
   3037    npixels = ((xb + 0xffff) >> 16) - left;
   3038 
   3039    offset = (pPriv->video_offset) + (top * dstPitch);
   3040 
   3041    if(pPriv->doubleBuffer) {
   3042 	unsigned char *RADEONMMIO = info->MMIO;
   3043 
   3044 	/* Wait for last flip to take effect */
   3045 	while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK));
   3046 
   3047 	offset += pPriv->currentBuffer * new_size;
   3048    }
   3049 
   3050    dst_start = info->FB + offset;
   3051 
   3052    switch(id) {
   3053    case FOURCC_YV12:
   3054    case FOURCC_I420:
   3055 	if (id == idconv) {
   3056 	    /* meh. Such a mess just for someone who wants to watch half the video clipped */
   3057 	    top &= ~1;
   3058 	    /* odd number of pixels? That may not work correctly */
   3059 	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
   3060 	    /* odd number of lines? Maybe... */
   3061 	    s2offset = srcPitch * (RADEON_ALIGN(height, 2));
   3062 	    s3offset = s2offset + srcPitch2 * ((height + 1) >> 1);
   3063 	    s2offset += (top >> 1) * srcPitch2 + (left >> 1);
   3064 	    s3offset += (top >> 1) * srcPitch2 + (left >> 1);
   3065 	    d2line = (height * dstPitch);
   3066 	    d3line = d2line + ((height + 1) >> 1) * (dstPitch >> 1);
   3067 	    nlines = ((yb + 0xffff) >> 16) - top;
   3068 	    d2line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
   3069 	    d3line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
   3070 	    if(id == FOURCC_YV12) {
   3071 		tmp = s2offset;
   3072 		s2offset = s3offset;
   3073 		s3offset = tmp;
   3074 	    }
   3075 	    RADEONCopyData(pScrn, buf + (top * srcPitch) + left, dst_start + left,
   3076 		srcPitch, dstPitch, nlines, npixels, 1);
   3077 	    RADEONCopyData(pScrn, buf + s2offset, dst_start + d2line + (left >> 1),
   3078 		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
   3079 	    RADEONCopyData(pScrn, buf + s3offset, dst_start + d3line + (left >> 1),
   3080 		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
   3081 	}
   3082 	else {
   3083 	    s2offset = srcPitch * height;
   3084 	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
   3085 	    s3offset = (srcPitch2 * (height >> 1)) + s2offset;
   3086 	    top &= ~1;
   3087 	    dst_start += left << 1;
   3088 	    tmp = ((top >> 1) * srcPitch2) + (left >> 1);
   3089 	    s2offset += tmp;
   3090 	    s3offset += tmp;
   3091 	    if(id == FOURCC_I420) {
   3092 		tmp = s2offset;
   3093 		s2offset = s3offset;
   3094 		s3offset = tmp;
   3095 	    }
   3096 	    nlines = ((yb + 0xffff) >> 16) - top;
   3097 	    RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left,
   3098 				 buf + s2offset, buf + s3offset, dst_start,
   3099 				 srcPitch, srcPitch2, dstPitch, nlines, npixels);
   3100 	}
   3101 	break;
   3102     case FOURCC_RGBT16:
   3103     case FOURCC_RGB16:
   3104     case FOURCC_UYVY:
   3105     case FOURCC_YUY2:
   3106     default:
   3107 	left <<= 1;
   3108 	buf += (top * srcPitch) + left;
   3109 	nlines = ((yb + 0xffff) >> 16) - top;
   3110 	dst_start += left;
   3111 	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2);
   3112 	break;
   3113     case FOURCC_RGBA32:
   3114 	buf += (top * srcPitch) + left*4;
   3115 	nlines = ((yb + 0xffff) >> 16) - top;
   3116 	dst_start += left*4;
   3117 	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4);
   3118     	break;
   3119     case FOURCC_RGB24:
   3120 	buf += (top * srcPitch) + left*3;
   3121 	nlines = ((yb + 0xffff) >> 16) - top;
   3122 	dst_start += left*4;
   3123 	RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels);
   3124     	break;
   3125     }
   3126 
   3127     /* update cliplist */
   3128     if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
   3129     {
   3130 	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
   3131 	/* draw these */
   3132 	if(pPriv->autopaint_colorkey)
   3133 	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
   3134     }
   3135 
   3136     /* FIXME: someone should look at these offsets, I don't think it makes sense how
   3137               they are handled throughout the source. */
   3138     RADEONDisplayVideo(pScrn, crtc, pPriv, idconv, pPriv->video_offset, offset,
   3139 		       offset + d2line, offset + d3line, offset, offset + d2line,
   3140 		       offset + d3line, width, height, dstPitch, xa, xb, ya,
   3141 		       &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
   3142 
   3143     pPriv->videoStatus = CLIENT_VIDEO_ON;
   3144 
   3145     info->VideoTimerCallback = RADEONVideoTimerCallback;
   3146 
   3147     return Success;
   3148 }
   3149 
   3150 
   3151 int
   3152 RADEONQueryImageAttributes(
   3153     ScrnInfoPtr pScrn,
   3154     int id,
   3155     unsigned short *w, unsigned short *h,
   3156     int *pitches, int *offsets
   3157 ){
   3158     const RADEONInfoRec * const info = RADEONPTR(pScrn);
   3159     int size, tmp;
   3160 
   3161     if(*w > info->xv_max_width) *w = info->xv_max_width;
   3162     if(*h > info->xv_max_height) *h = info->xv_max_height;
   3163 
   3164     *w = RADEON_ALIGN(*w, 2);
   3165     if(offsets) offsets[0] = 0;
   3166 
   3167     switch(id) {
   3168     case FOURCC_YV12:
   3169     case FOURCC_I420:
   3170 	*h = RADEON_ALIGN(*h, 2);
   3171 	size = RADEON_ALIGN(*w, 4);
   3172 	if(pitches) pitches[0] = size;
   3173 	size *= *h;
   3174 	if(offsets) offsets[1] = size;
   3175 	tmp = RADEON_ALIGN(*w >> 1, 4);
   3176 	if(pitches) pitches[1] = pitches[2] = tmp;
   3177 	tmp *= (*h >> 1);
   3178 	size += tmp;
   3179 	if(offsets) offsets[2] = size;
   3180 	size += tmp;
   3181 	break;
   3182     case FOURCC_RGBA32:
   3183 	size = *w << 2;
   3184 	if(pitches) pitches[0] = size;
   3185 	size *= *h;
   3186 	break;
   3187     case FOURCC_RGB24:
   3188 	size = *w * 3;
   3189 	if(pitches) pitches[0] = size;
   3190 	size *= *h;
   3191 	break;
   3192     case FOURCC_RGBT16:
   3193     case FOURCC_RGB16:
   3194     case FOURCC_UYVY:
   3195     case FOURCC_YUY2:
   3196     default:
   3197 	size = *w << 1;
   3198 	if(pitches) pitches[0] = size;
   3199 	size *= *h;
   3200 	break;
   3201     }
   3202 
   3203     return size;
   3204 }
   3205 
   3206 static void
   3207 RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now)
   3208 {
   3209     RADEONInfoPtr info = RADEONPTR(pScrn);
   3210     RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
   3211 
   3212     if(pPriv->videoStatus & TIMER_MASK) {
   3213 	if(pPriv->videoStatus & OFF_TIMER) {
   3214 	    if(pPriv->offTime < now) {
   3215 		unsigned char *RADEONMMIO = info->MMIO;
   3216 		OUTREG(RADEON_OV0_SCALE_CNTL, 0);
   3217 		pPriv->videoStatus = FREE_TIMER;
   3218 		pPriv->freeTime = now + FREE_DELAY;
   3219 	    }
   3220 	} else {  /* FREE_TIMER */
   3221 	    if(pPriv->freeTime < now) {
   3222 		RADEONFreeVideoMemory(pScrn, pPriv);
   3223 		pPriv->videoStatus = 0;
   3224 		info->VideoTimerCallback = NULL;
   3225 	    }
   3226 	}
   3227     } else  /* shouldn't get here */
   3228 	info->VideoTimerCallback = NULL;
   3229 }
   3230 
   3231 /****************** Offscreen stuff ***************/
   3232 typedef struct {
   3233   void *surface_memory;
   3234   Bool isOn;
   3235 } OffscreenPrivRec, * OffscreenPrivPtr;
   3236 
   3237 static int
   3238 RADEONAllocateSurface(
   3239     ScrnInfoPtr pScrn,
   3240     int id,
   3241     unsigned short w,
   3242     unsigned short h,
   3243     XF86SurfacePtr surface
   3244 ){
   3245     int offset, pitch, size;
   3246     OffscreenPrivPtr pPriv;
   3247     void *surface_memory = NULL;
   3248     if((w > 1024) || (h > 1024))
   3249 	return BadAlloc;
   3250 
   3251     w = RADEON_ALIGN(w, 2);
   3252     pitch = RADEON_ALIGN(w << 1, 16);
   3253     size = pitch * h;
   3254 
   3255     offset = radeon_legacy_allocate_memory(pScrn, &surface_memory, size, 64,
   3256 		    RADEON_GEM_DOMAIN_VRAM);
   3257     if (offset == 0)
   3258 	return BadAlloc;
   3259 
   3260     surface->width = w;
   3261     surface->height = h;
   3262 
   3263     if(!(surface->pitches = malloc(sizeof(int)))) {
   3264 	radeon_legacy_free_memory(pScrn, surface_memory);
   3265 	return BadAlloc;
   3266     }
   3267     if(!(surface->offsets = malloc(sizeof(int)))) {
   3268 	free(surface->pitches);
   3269 	radeon_legacy_free_memory(pScrn, surface_memory);
   3270 	return BadAlloc;
   3271     }
   3272     if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) {
   3273 	free(surface->pitches);
   3274 	free(surface->offsets);
   3275 	radeon_legacy_free_memory(pScrn, surface_memory);
   3276 	return BadAlloc;
   3277     }
   3278 
   3279     pPriv->surface_memory = surface_memory;
   3280     pPriv->isOn = FALSE;
   3281 
   3282     surface->pScrn = pScrn;
   3283     surface->id = id;
   3284     surface->pitches[0] = pitch;
   3285     surface->offsets[0] = offset;
   3286     surface->devPrivate.ptr = (pointer)pPriv;
   3287 
   3288     return Success;
   3289 }
   3290 
   3291 static int
   3292 RADEONStopSurface(
   3293     XF86SurfacePtr surface
   3294 ){
   3295   OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
   3296   RADEONInfoPtr info = RADEONPTR(surface->pScrn);
   3297   unsigned char *RADEONMMIO = info->MMIO;
   3298 
   3299   if(pPriv->isOn) {
   3300 	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
   3301 	pPriv->isOn = FALSE;
   3302   }
   3303   return Success;
   3304 }
   3305 
   3306 
   3307 static int
   3308 RADEONFreeSurface(
   3309     XF86SurfacePtr surface
   3310 ){
   3311     ScrnInfoPtr pScrn = surface->pScrn;
   3312     OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
   3313 
   3314     if(pPriv->isOn)
   3315 	RADEONStopSurface(surface);
   3316     radeon_legacy_free_memory(pScrn, pPriv->surface_memory);
   3317     pPriv->surface_memory = NULL;
   3318     free(surface->pitches);
   3319     free(surface->offsets);
   3320     free(surface->devPrivate.ptr);
   3321 
   3322     return Success;
   3323 }
   3324 
   3325 static int
   3326 RADEONGetSurfaceAttribute(
   3327     ScrnInfoPtr pScrn,
   3328     Atom attribute,
   3329     INT32 *value
   3330 ){
   3331    return RADEONGetPortAttribute(pScrn, attribute, value,
   3332 		(pointer)(GET_PORT_PRIVATE(pScrn)));
   3333 }
   3334 
   3335 static int
   3336 RADEONSetSurfaceAttribute(
   3337     ScrnInfoPtr pScrn,
   3338     Atom attribute,
   3339     INT32 value
   3340 ){
   3341    return RADEONSetPortAttribute(pScrn, attribute, value,
   3342 		(pointer)(GET_PORT_PRIVATE(pScrn)));
   3343 }
   3344 
   3345 
   3346 static int
   3347 RADEONDisplaySurface(
   3348     XF86SurfacePtr surface,
   3349     short src_x, short src_y,
   3350     short drw_x, short drw_y,
   3351     short src_w, short src_h,
   3352     short drw_w, short drw_h,
   3353     RegionPtr clipBoxes
   3354 ){
   3355     OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
   3356     ScrnInfoPtr pScrn = surface->pScrn;
   3357     RADEONInfoPtr info = RADEONPTR(pScrn);
   3358     RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
   3359 
   3360     INT32 xa, ya, xb, yb;
   3361     BoxRec dstBox;
   3362     xf86CrtcPtr crtc;
   3363 
   3364     if (src_w > (drw_w << 4))
   3365 	drw_w = src_w >> 4;
   3366     if (src_h > (drw_h << 4))
   3367 	drw_h = src_h >> 4;
   3368 
   3369     xa = src_x;
   3370     xb = src_x + src_w;
   3371     ya = src_y;
   3372     yb = src_y + src_h;
   3373 
   3374     dstBox.x1 = drw_x;
   3375     dstBox.x2 = drw_x + drw_w;
   3376     dstBox.y1 = drw_y;
   3377     dstBox.y2 = drw_y + drw_h;
   3378 
   3379     if (!radeon_crtc_clip_video(pScrn, &crtc, portPriv->desired_crtc,
   3380 				&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
   3381 				surface->width, surface->height))
   3382         return Success;
   3383 
   3384    if (!crtc) {
   3385        if (pPriv->isOn) {
   3386 	   unsigned char *RADEONMMIO = info->MMIO;
   3387 	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
   3388 	   pPriv->isOn = FALSE;
   3389        }
   3390        return Success;
   3391    }
   3392 
   3393     dstBox.x1 -= crtc->x;
   3394     dstBox.x2 -= crtc->x;
   3395     dstBox.y1 -= crtc->y;
   3396     dstBox.y2 -= crtc->y;
   3397 
   3398 #if 0
   3399     /* this isn't needed */
   3400     RADEONResetVideo(pScrn);
   3401 #endif
   3402     RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id,
   3403 		       surface->offsets[0], surface->offsets[0],
   3404 		       surface->offsets[0], surface->offsets[0],
   3405 		       surface->offsets[0], surface->offsets[0],
   3406 		       surface->offsets[0], surface->width, surface->height,
   3407 		       surface->pitches[0], xa, xb, ya, &dstBox, src_w, src_h,
   3408 		       drw_w, drw_h, METHOD_BOB);
   3409 
   3410     if (portPriv->autopaint_colorkey)
   3411 	xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
   3412 
   3413     pPriv->isOn = TRUE;
   3414     /* we've prempted the XvImage stream so set its free timer */
   3415     if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
   3416 	REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
   3417 	UpdateCurrentTime();
   3418 	portPriv->videoStatus = FREE_TIMER;
   3419 	portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
   3420 	info->VideoTimerCallback = RADEONVideoTimerCallback;
   3421     }
   3422 
   3423     return Success;
   3424 }
   3425 
   3426 
   3427 static void
   3428 RADEONInitOffscreenImages(ScreenPtr pScreen)
   3429 {
   3430 /*  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   3431     RADEONInfoPtr info = RADEONPTR(pScrn); */
   3432     XF86OffscreenImagePtr offscreenImages;
   3433     /* need to free this someplace */
   3434 
   3435     if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec))))
   3436 	return;
   3437 
   3438     offscreenImages[0].image = &Images[0];
   3439     offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*|
   3440 			       VIDEO_CLIP_TO_VIEWPORT*/;
   3441     offscreenImages[0].alloc_surface = RADEONAllocateSurface;
   3442     offscreenImages[0].free_surface = RADEONFreeSurface;
   3443     offscreenImages[0].display = RADEONDisplaySurface;
   3444     offscreenImages[0].stop = RADEONStopSurface;
   3445     offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute;
   3446     offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute;
   3447     offscreenImages[0].max_width = 2047;
   3448     offscreenImages[0].max_height = 2047;
   3449     offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
   3450     offscreenImages[0].attributes = Attributes;
   3451 
   3452     xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
   3453 }
   3454 
   3455          /* TV-in functions */
   3456 
   3457 static int
   3458 RADEONPutVideo(
   3459   ScrnInfoPtr pScrn,
   3460   short src_x, short src_y,
   3461   short drw_x, short drw_y,
   3462   short src_w, short src_h,
   3463   short drw_w, short drw_h,
   3464   RegionPtr clipBoxes, pointer data,
   3465   DrawablePtr pDraw
   3466 ){
   3467    RADEONInfoPtr info = RADEONPTR(pScrn);
   3468    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
   3469    unsigned char *RADEONMMIO = info->MMIO;
   3470    INT32 xa, xb, ya, yb, top;
   3471    unsigned int pitch, new_size, alloc_size;
   3472    unsigned int offset1, offset2, offset3, offset4, s2offset, s3offset;
   3473    unsigned int vbi_offset0, vbi_offset1;
   3474    int srcPitch, srcPitch2, dstPitch;
   3475    int bpp;
   3476    BoxRec dstBox;
   3477    uint32_t id, display_base;
   3478    int width, height;
   3479    int mult;
   3480    int vbi_line_width, vbi_start, vbi_end;
   3481    xf86CrtcPtr crtc;
   3482 
   3483     RADEON_SYNC(info, pScrn);
   3484    /*
   3485     * s2offset, s3offset - byte offsets into U and V plane of the
   3486     *                      source where copying starts.  Y plane is
   3487     *                      done by editing "buf".
   3488     *
   3489     * offset - byte offset to the first line of the destination.
   3490     *
   3491     * dst_start - byte address to the first displayed pel.
   3492     *
   3493     */
   3494 
   3495    /* make the compiler happy */
   3496    s2offset = s3offset = srcPitch2 = 0;
   3497 
   3498    if(src_w > (drw_w << 4))
   3499         drw_w = src_w >> 4;
   3500    if(src_h > (drw_h << 4))
   3501         drw_h = src_h >> 4;
   3502 
   3503    /* Clip */
   3504    xa = src_x;
   3505    xb = src_x + src_w;
   3506    ya = src_y;
   3507    yb = src_y + src_h;
   3508 
   3509    dstBox.x1 = drw_x;
   3510    dstBox.x2 = drw_x + drw_w;
   3511    dstBox.y1 = drw_y;
   3512    dstBox.y2 = drw_y + drw_h;
   3513 
   3514    width = InputVideoEncodings[pPriv->encoding].width;
   3515    height = InputVideoEncodings[pPriv->encoding].height;
   3516 
   3517    vbi_line_width = 798*2;
   3518    if(width<=640)
   3519        vbi_line_width = 0x640; /* 1600 actually */
   3520    else
   3521        vbi_line_width = 2000; /* might need adjustment */
   3522 
   3523    if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
   3524 			       &dstBox, &xa, &xb, &ya, &yb,
   3525 			       clipBoxes, width, height))
   3526        return Success;
   3527 
   3528    if (!crtc) {
   3529        if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
   3530 	   unsigned char *RADEONMMIO = info->MMIO;
   3531 	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
   3532 	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
   3533        }
   3534        return Success;
   3535    }
   3536 
   3537    dstBox.x1 -= crtc->x;
   3538    dstBox.x2 -= crtc->x;
   3539    dstBox.y1 -= crtc->y;
   3540    dstBox.y2 -= crtc->y;
   3541 
   3542    bpp = pScrn->bitsPerPixel >> 3;
   3543    pitch = bpp * pScrn->displayWidth;
   3544 
   3545    switch(pPriv->overlay_deinterlacing_method){
   3546         case METHOD_BOB:
   3547         case METHOD_SINGLE:
   3548                 mult=2;
   3549                 break;
   3550         case METHOD_WEAVE:
   3551         case METHOD_ADAPTIVE:
   3552                 mult=4;
   3553                 break;
   3554         default:
   3555                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n");
   3556                 mult=4;
   3557         }
   3558 
   3559    id = FOURCC_YUY2;
   3560 
   3561    top = ya>>16;
   3562 #if 0
   3563    /* setting the ID above makes this useful - needs revisiting */
   3564    switch(id) {
   3565    case FOURCC_YV12:
   3566    case FOURCC_I420:
   3567         top &= ~1;
   3568         dstPitch = RADEON_ALIGN(width << 1, 16);
   3569         srcPitch = RADEON_ALIGN(width, 4);
   3570         s2offset = srcPitch * height;
   3571         srcPitch2 = RADEON_ALIGN(width >> 1, 4);
   3572         s3offset = (srcPitch2 * (height >> 1)) + s2offset;
   3573         break;
   3574    case FOURCC_UYVY:
   3575    case FOURCC_YUY2:
   3576    default:
   3577         dstPitch = RADEON_ALIGN(width<<1, 16);
   3578         srcPitch = (width<<1);
   3579         break;
   3580    }
   3581 #else
   3582    dstPitch = RADEON_ALIGN(width << 1, 16);
   3583    srcPitch = (width<<1);
   3584 #endif
   3585 
   3586    new_size = dstPitch * height;
   3587    new_size = new_size + 0x1f; /* for aligning */
   3588    alloc_size = new_size * mult;
   3589    if (pPriv->capture_vbi_data)
   3590       alloc_size += 2 * 2 * vbi_line_width * 21;
   3591 
   3592    pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
   3593 						      (pPriv->doubleBuffer ?
   3594 						      (new_size * 2) : new_size), 64,
   3595 						      RADEON_GEM_DOMAIN_GTT);
   3596    if (pPriv->video_offset == 0)
   3597       return BadAlloc;
   3598 
   3599 /* I have suspicion that capture engine must be active _before_ Rage Theatre
   3600    is being manipulated with.. */
   3601 
   3602    RADEONWaitForIdleMMIO(pScrn);
   3603    display_base=INREG(RADEON_DISPLAY_BASE_ADDR);
   3604 
   3605 /*   RADEONWaitForFifo(pScrn, 15); */
   3606 
   3607    switch(pPriv->overlay_deinterlacing_method){
   3608         case METHOD_BOB:
   3609         case METHOD_SINGLE:
   3610            offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
   3611            offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
   3612            offset3 = offset1;
   3613            offset4 = offset2;
   3614            break;
   3615         case METHOD_WEAVE:
   3616            offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
   3617            offset2 = offset1+dstPitch;
   3618            offset3 = RADEON_ALIGN(pPriv->video_offset + 2 * new_size, 0x10);
   3619            offset4 = offset3+dstPitch;
   3620            break;
   3621         default:
   3622            offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
   3623            offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
   3624            offset3 = offset1;
   3625            offset4 = offset2;
   3626         }
   3627 
   3628    OUTREG(RADEON_CAP0_BUF0_OFFSET,        offset1+display_base);
   3629    OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET,   offset2+display_base);
   3630    OUTREG(RADEON_CAP0_BUF1_OFFSET,        offset3+display_base);
   3631    OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET,   offset4+display_base);
   3632 
   3633    OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base);
   3634 
   3635    if(pPriv->capture_vbi_data){
   3636         if ((pPriv->encoding==2)||(pPriv->encoding==8)) {
   3637             /* PAL, SECAM */
   3638             vbi_start = 5;
   3639             vbi_end = 21;
   3640         } else {
   3641             /* NTSC */
   3642             vbi_start = 8;
   3643             vbi_end = 20;
   3644         }
   3645 
   3646         vbi_offset0 = RADEON_ALIGN(pPriv->video_offset + mult * new_size * bpp, 0x10);
   3647         vbi_offset1 = vbi_offset0 + dstPitch*20;
   3648         OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base);
   3649         OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base);
   3650         OUTREG(RADEON_CAP0_VBI2_OFFSET, 0);
   3651         OUTREG(RADEON_CAP0_VBI3_OFFSET, 0);
   3652         OUTREG(RADEON_CAP0_VBI_V_WINDOW, vbi_start | (vbi_end<<16));
   3653         OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16);
   3654         }
   3655 
   3656    OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2);
   3657    OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16);
   3658    OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1));
   3659    if(mult==2){
   3660            OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB);
   3661            } else {
   3662            OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE);
   3663            }
   3664    OUTREG(RADEON_CAP0_DEBUG, 0);
   3665 
   3666    OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01);
   3667    OUTREG(RADEON_TEST_DEBUG_CNTL, 0);
   3668 
   3669    if(! pPriv->video_stream_active)
   3670    {
   3671 
   3672       RADEONWaitForIdleMMIO(pScrn);
   3673       OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 );
   3674       OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0);
   3675       OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK);
   3676       OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11);
   3677       if(pPriv->theatre != NULL)
   3678       {
   3679          RADEON_RT_SetEncoding(pScrn, pPriv);
   3680       }
   3681       if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
   3682       if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
   3683       if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
   3684       if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
   3685    }
   3686 
   3687 
   3688    /* update cliplist */
   3689    if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
   3690         REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
   3691         /* draw these */
   3692         if(pPriv->autopaint_colorkey)
   3693 	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
   3694    }
   3695 
   3696    RADEONDisplayVideo(pScrn, crtc, pPriv, id, pPriv->video_offset,
   3697 		      offset1+top*srcPitch, offset2+top*srcPitch,
   3698 		      offset3+top*srcPitch, offset4+top*srcPitch,
   3699 		      offset1+top*srcPitch, offset2+top*srcPitch, width, height,
   3700 		      dstPitch*mult/2, xa, xb, ya, &dstBox, src_w, src_h*mult/2,
   3701 		      drw_w, drw_h, pPriv->overlay_deinterlacing_method);
   3702 
   3703    RADEONWaitForFifo(pScrn, 1);
   3704    OUTREG(RADEON_OV0_REG_LOAD_CNTL,  RADEON_REG_LD_CTL_LOCK);
   3705    RADEONWaitForIdleMMIO(pScrn);
   3706    while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
   3707 
   3708 
   3709    switch(pPriv->overlay_deinterlacing_method){
   3710         case METHOD_BOB:
   3711            OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
   3712            OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/
   3713                 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
   3714            break;
   3715         case METHOD_SINGLE:
   3716            OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
   3717            OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
   3718                 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
   3719            break;
   3720         case METHOD_WEAVE:
   3721            OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28));
   3722            OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0  |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
   3723                 | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN
   3724                 /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */
   3725                 /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */
   3726                 |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE);
   3727            break;
   3728         default:
   3729            OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
   3730            OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
   3731                 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
   3732         }
   3733 
   3734 
   3735    RADEONWaitForIdleMMIO(pScrn);
   3736    OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
   3737    OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
   3738 
   3739    OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
   3740 
   3741 #if 0
   3742    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL));
   3743 /*   OUTREG(RADEON_OV0_FLAG_CNTL, 8); */
   3744    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL));
   3745    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS));
   3746 
   3747 /*   OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */
   3748 #endif
   3749 
   3750    pPriv->videoStatus = CLIENT_VIDEO_ON;
   3751    pPriv->video_stream_active = TRUE;
   3752 
   3753    info->VideoTimerCallback = RADEONVideoTimerCallback;
   3754 
   3755    return Success;
   3756 }
   3757         /* miscellaneous TV-in helper functions */
   3758 
   3759 static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv)
   3760 {
   3761     /* Adjust PAL/SECAM constants for FI1216MF tuner */
   3762     if((((pPriv->tuner_type & 0xf)==5) ||
   3763         ((pPriv->tuner_type & 0xf)==11)||
   3764         ((pPriv->tuner_type & 0xf)==14))
   3765         && (pPriv->fi1236!=NULL))
   3766     {
   3767         if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/
   3768         {
   3769            pPriv->fi1236->parm.band_low = 0xA1;
   3770            pPriv->fi1236->parm.band_mid = 0x91;
   3771            pPriv->fi1236->parm.band_high = 0x31;
   3772         }
   3773         if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/
   3774         {
   3775            pPriv->fi1236->parm.band_low = 0xA3;
   3776            pPriv->fi1236->parm.band_mid = 0x93;
   3777            pPriv->fi1236->parm.band_high = 0x33;
   3778         }
   3779     }
   3780 
   3781 }
   3782 
   3783 static void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
   3784 {
   3785 int width, height;
   3786 RADEONWaitForIdleMMIO(pScrn);
   3787 
   3788 /* Disable VBI capture for anything but TV tuner */
   3789 switch(pPriv->encoding){
   3790 	case 2:
   3791 	case 5:
   3792 	case 8:
   3793 		pPriv->capture_vbi_data=1;
   3794 		break;
   3795 	default:
   3796 		pPriv->capture_vbi_data=0;
   3797 	}
   3798 
   3799 switch(pPriv->encoding){
   3800         case 1:
   3801                 xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
   3802                 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
   3803                 pPriv->v=25;
   3804                 break;
   3805         case 2:
   3806                 xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
   3807                 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
   3808                 pPriv->v=25;
   3809                 break;
   3810         case 3:
   3811                 xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
   3812                 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
   3813                 pPriv->v=25;
   3814                 break;
   3815         case 4:
   3816                 xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE,0);
   3817                 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
   3818                 pPriv->v=23;
   3819                 break;
   3820         case 5:
   3821                 xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
   3822                 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
   3823                 pPriv->v=23;
   3824                 break;
   3825         case 6:
   3826                 xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
   3827                 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
   3828                 pPriv->v=23;
   3829                 break;
   3830         case 7:
   3831                 xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE, 0);
   3832                 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
   3833                 pPriv->v=25;
   3834                 break;
   3835         case 8:
   3836                 xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
   3837                 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
   3838                 pPriv->v=25;
   3839                 break;
   3840         case 9:
   3841                 xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
   3842                 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
   3843                 pPriv->v=25;
   3844                 break;
   3845         case 10:
   3846                 xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
   3847                 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
   3848                 pPriv->v=25;
   3849                 break;
   3850         case 11:
   3851                 xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
   3852                 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
   3853                 pPriv->v=25;
   3854                 break;
   3855         case 12:
   3856                 xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
   3857                 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
   3858                 pPriv->v=25;
   3859                 break;
   3860         default:
   3861                 pPriv->v=0;
   3862                 return;
   3863         }
   3864 xf86_RT_SetInterlace(pPriv->theatre, 1);
   3865 width = InputVideoEncodings[pPriv->encoding].width;
   3866 height = InputVideoEncodings[pPriv->encoding].height;
   3867 xf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data);
   3868 }
   3869 
   3870 static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv)
   3871 {
   3872 xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
   3873 switch(pPriv->encoding){
   3874         case 1:
   3875                 pPriv->msp3430->standard = MSP3430_PAL;
   3876                 pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
   3877                 break;
   3878         case 2:
   3879                 pPriv->msp3430->standard = MSP3430_PAL;
   3880                 pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
   3881                 break;
   3882         case 3:
   3883                 pPriv->msp3430->standard = MSP3430_PAL;
   3884                 pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
   3885                 break;
   3886         case 4:
   3887                 pPriv->msp3430->standard = MSP3430_NTSC;
   3888                 pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
   3889                 break;
   3890         case 5:
   3891                 pPriv->msp3430->standard = MSP3430_NTSC;
   3892                 pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
   3893                 break;
   3894         case 6:
   3895                 pPriv->msp3430->standard = MSP3430_NTSC;
   3896                 pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
   3897                 break;
   3898         case 7:
   3899                 pPriv->msp3430->standard = MSP3430_SECAM;
   3900                 pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
   3901                 break;
   3902         case 8:
   3903                 pPriv->msp3430->standard = MSP3430_SECAM;
   3904                 pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
   3905                 break;
   3906         case 9:
   3907                 pPriv->msp3430->standard = MSP3430_SECAM;
   3908                 pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
   3909                 break;
   3910         case 10:
   3911                 pPriv->msp3430->standard = MSP3430_SECAM;
   3912                 pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
   3913                 break;
   3914         case 11:
   3915                 pPriv->msp3430->standard = MSP3430_SECAM;
   3916                 pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
   3917                 break;
   3918         case 12:
   3919                 pPriv->msp3430->standard = MSP3430_SECAM;
   3920                 pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
   3921                 break;
   3922         default:
   3923                 return;
   3924         }
   3925 xf86_InitMSP3430(pPriv->msp3430);
   3926 xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
   3927 }
   3928 
   3929 static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv)
   3930 {
   3931 TDA9885Ptr t=pPriv->tda9885;
   3932 
   3933 switch(pPriv->encoding){
   3934                 /* PAL */
   3935         case 1:
   3936         case 2:
   3937         case 3:
   3938                 t->standard_video_if=2;
   3939                 t->standard_sound_carrier=1;
   3940 					 t->modulation=2; /* negative FM */
   3941                 break;
   3942                 /* NTSC */
   3943         case 4:
   3944         case 5:
   3945         case 6:
   3946                 t->standard_video_if=1;
   3947                 t->standard_sound_carrier=0;
   3948 					 t->modulation=2; /* negative FM */
   3949                 break;
   3950                 /* SECAM */
   3951         case 7:
   3952         case 8:
   3953         case 9:
   3954         case 10:
   3955         case 11:
   3956         case 12:
   3957                 t->standard_video_if=0;
   3958                 t->standard_sound_carrier=3;
   3959                 t->modulation=0; /* positive AM */
   3960                 break;
   3961         default:
   3962                 return;
   3963         }
   3964 xf86_tda9885_setparameters(pPriv->tda9885);
   3965 xf86_tda9885_getstatus(pPriv->tda9885);
   3966 xf86_tda9885_dumpstatus(pPriv->tda9885);
   3967 }
   3968 
   3969 static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv)
   3970 {
   3971 /* at the moment this only affect MT2032 */
   3972 switch(pPriv->encoding){
   3973                 /* PAL */
   3974         case 1:
   3975         case 2:
   3976         case 3:
   3977 		pPriv->fi1236->video_if=38.900;
   3978                 break;
   3979                 /* NTSC */
   3980         case 4:
   3981         case 5:
   3982         case 6:
   3983 		pPriv->fi1236->video_if=45.7812;
   3984 		pPriv->fi1236->video_if=45.750;
   3985 		pPriv->fi1236->video_if=45.125;
   3986                 break;
   3987                 /* SECAM */
   3988         case 7:
   3989         case 8:
   3990         case 9:
   3991         case 10:
   3992         case 11:
   3993         case 12:
   3994 		pPriv->fi1236->video_if=58.7812;
   3995                 break;
   3996         default:
   3997                 return;
   3998         }
   3999 }
   4000 
   4001