radeon_video.c revision 7821949a
1de2362d3Smrg
2de2362d3Smrg#ifdef HAVE_CONFIG_H
3de2362d3Smrg#include "config.h"
4de2362d3Smrg#endif
5de2362d3Smrg
6de2362d3Smrg#include <stdlib.h>
7de2362d3Smrg#include <string.h>
8de2362d3Smrg#include <stdio.h>
9de2362d3Smrg#include <math.h>
10de2362d3Smrg
11de2362d3Smrg#include "radeon.h"
12de2362d3Smrg#include "radeon_reg.h"
137821949aSmrg#include "radeon_macros.h"
14de2362d3Smrg#include "radeon_probe.h"
15de2362d3Smrg#include "radeon_video.h"
16de2362d3Smrg
17de2362d3Smrg#include "xf86.h"
18de2362d3Smrg#include "dixstruct.h"
197821949aSmrg#include "atipciids.h"
207821949aSmrg#include "xf86fbman.h"
21de2362d3Smrg
22de2362d3Smrg/* DPMS */
23de2362d3Smrg#ifdef HAVE_XEXTPROTO_71
24de2362d3Smrg#include <X11/extensions/dpmsconst.h>
25de2362d3Smrg#else
26de2362d3Smrg#define DPMS_SERVER
27de2362d3Smrg#include <X11/extensions/dpms.h>
28de2362d3Smrg#endif
29de2362d3Smrg
30de2362d3Smrg#include <X11/extensions/Xv.h>
31de2362d3Smrg#include "fourcc.h"
32de2362d3Smrg
337821949aSmrg#include "theatre_detect.h"
347821949aSmrg#include "theatre_reg.h"
357821949aSmrg#include "fi1236.h"
367821949aSmrg#include "msp3430.h"
377821949aSmrg#include "tda9885.h"
387821949aSmrg
39de2362d3Smrg#define OFF_DELAY       250  /* milliseconds */
40de2362d3Smrg#define FREE_DELAY      15000
41de2362d3Smrg
42de2362d3Smrg#define OFF_TIMER       0x01
43de2362d3Smrg#define FREE_TIMER      0x02
44de2362d3Smrg#define CLIENT_VIDEO_ON 0x04
45de2362d3Smrg
467821949aSmrg#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
477821949aSmrg
487821949aSmrg/* capture config constants */
497821949aSmrg#define BUF_TYPE_FIELD          0
507821949aSmrg#define BUF_TYPE_ALTERNATING    1
517821949aSmrg#define BUF_TYPE_FRAME          2
527821949aSmrg
537821949aSmrg
547821949aSmrg#define BUF_MODE_SINGLE         0
557821949aSmrg#define BUF_MODE_DOUBLE         1
567821949aSmrg#define BUF_MODE_TRIPLE         2
577821949aSmrg/* CAP0_CONFIG values */
587821949aSmrg
597821949aSmrg#define FORMAT_BROOKTREE        0
607821949aSmrg#define FORMAT_CCIR656          1
617821949aSmrg#define FORMAT_ZV               2
627821949aSmrg#define FORMAT_VIP16            3
637821949aSmrg#define FORMAT_TRANSPORT        4
647821949aSmrg
657821949aSmrg#define ENABLE_RADEON_CAPTURE_WEAVE (RADEON_CAP0_CONFIG_CONTINUOS \
667821949aSmrg                        | (BUF_MODE_DOUBLE <<7) \
677821949aSmrg                        | (BUF_TYPE_FRAME << 4) \
687821949aSmrg                        | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
697821949aSmrg                        | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
707821949aSmrg                        | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
717821949aSmrg                        | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
727821949aSmrg
737821949aSmrg#define ENABLE_RADEON_CAPTURE_BOB (RADEON_CAP0_CONFIG_CONTINUOS \
747821949aSmrg                        | (BUF_MODE_SINGLE <<7)  \
757821949aSmrg                        | (BUF_TYPE_ALTERNATING << 4) \
767821949aSmrg                        | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
777821949aSmrg                        | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
787821949aSmrg                        | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
797821949aSmrg                        | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
807821949aSmrg
817821949aSmrg
827821949aSmrgstatic void RADEONInitOffscreenImages(ScreenPtr);
837821949aSmrg
847821949aSmrgstatic XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr);
857821949aSmrgstatic int  RADEONPutImage(ScrnInfoPtr, short, short, short, short, short,
867821949aSmrg			short, short, short, int, unsigned char*, short,
877821949aSmrg			short, Bool, RegionPtr, pointer,
887821949aSmrg			DrawablePtr);
897821949aSmrgstatic void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
907821949aSmrgstatic int RADEONPutVideo(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y,
917821949aSmrg                        short src_w, short src_h, short drw_w, short drw_h,
927821949aSmrg			RegionPtr clipBoxes, pointer data, DrawablePtr pDraw);
937821949aSmrg
947821949aSmrgstatic void RADEON_board_setmisc(RADEONPortPrivPtr pPriv);
957821949aSmrgstatic void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
967821949aSmrgstatic void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv);
977821949aSmrgstatic void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv);
987821949aSmrgstatic void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv);
997821949aSmrg
1007821949aSmrgstatic Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
1017821949aSmrgstatic Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
1027821949aSmrgstatic Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
1037821949aSmrgstatic Atom xvGamma, xvColorspace;
1047821949aSmrgstatic Atom xvCRTC;
1057821949aSmrgstatic Atom xvEncoding, xvFrequency, xvVolume, xvMute,
1067821949aSmrg	     xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
1077821949aSmrg	     xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
1087821949aSmrg	     xvLocationID, xvDeviceID, xvInstanceID, xvDumpStatus,
1097821949aSmrg	     xvAdjustment;
1107821949aSmrg
1117821949aSmrgstatic Atom xvOvAlpha, xvGrAlpha, xvAlphaMode;
1127821949aSmrg
113de2362d3Smrg#define GET_PORT_PRIVATE(pScrn) \
114de2362d3Smrg   (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
115de2362d3Smrg
116de2362d3Smrgstatic void
117de2362d3Smrgradeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
118de2362d3Smrg{
119de2362d3Smrg    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
120de2362d3Smrg    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
121de2362d3Smrg    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
122de2362d3Smrg    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
123de2362d3Smrg
124de2362d3Smrg    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
125de2362d3Smrg	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
126de2362d3Smrg}
127de2362d3Smrg
128de2362d3Smrgstatic void
129de2362d3Smrgradeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
130de2362d3Smrg{
131de2362d3Smrg    if (crtc->enabled) {
132de2362d3Smrg	crtc_box->x1 = crtc->x;
133de2362d3Smrg	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
134de2362d3Smrg	crtc_box->y1 = crtc->y;
135de2362d3Smrg	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
136de2362d3Smrg    } else
137de2362d3Smrg	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
138de2362d3Smrg}
139de2362d3Smrg
140de2362d3Smrgstatic int
141de2362d3Smrgradeon_box_area(BoxPtr box)
142de2362d3Smrg{
143de2362d3Smrg    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
144de2362d3Smrg}
145de2362d3Smrg
1467821949aSmrgstatic Bool
1477821949aSmrgradeon_crtc_is_enabled(xf86CrtcPtr crtc)
148de2362d3Smrg{
1497821949aSmrg    RADEONCrtcPrivatePtr radeon_crtc;
1507821949aSmrg
1517821949aSmrg#ifdef XF86DRM_MODE
1527821949aSmrg    if (RADEONPTR(crtc->scrn)->cs) {
1537821949aSmrg	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1547821949aSmrg	return drmmode_crtc->dpms_mode == DPMSModeOn;
1557821949aSmrg    }
1567821949aSmrg#endif
1577821949aSmrg
1587821949aSmrg    radeon_crtc = crtc->driver_private;
1597821949aSmrg    return radeon_crtc->enabled;
160de2362d3Smrg}
161de2362d3Smrg
162de2362d3Smrgxf86CrtcPtr
1637821949aSmrgradeon_pick_best_crtc(ScrnInfoPtr pScrn,
164de2362d3Smrg		      int x1, int x2, int y1, int y2)
165de2362d3Smrg{
166de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1677821949aSmrg    int			coverage, best_coverage, c;
168de2362d3Smrg    BoxRec		box, crtc_box, cover_box;
169de2362d3Smrg    RROutputPtr         primary_output = NULL;
170de2362d3Smrg    xf86CrtcPtr         best_crtc = NULL, primary_crtc = NULL;
171de2362d3Smrg
172de2362d3Smrg    if (!pScrn->vtSema)
173de2362d3Smrg	return NULL;
174de2362d3Smrg
175de2362d3Smrg    box.x1 = x1;
176de2362d3Smrg    box.x2 = x2;
177de2362d3Smrg    box.y1 = y1;
178de2362d3Smrg    box.y2 = y2;
179de2362d3Smrg    best_coverage = 0;
180de2362d3Smrg
181de2362d3Smrg    /* Prefer the CRTC of the primary output */
1827821949aSmrg#ifdef HAS_DIXREGISTERPRIVATEKEY
183de2362d3Smrg    if (dixPrivateKeyRegistered(rrPrivKey))
1847821949aSmrg#endif
185de2362d3Smrg    {
186de2362d3Smrg	primary_output = RRFirstOutput(pScrn->pScreen);
187de2362d3Smrg    }
188de2362d3Smrg    if (primary_output && primary_output->crtc)
189de2362d3Smrg	primary_crtc = primary_output->crtc->devPrivate;
190de2362d3Smrg
1917821949aSmrg    for (c = 0; c < xf86_config->num_crtc; c++) {
1927821949aSmrg	xf86CrtcPtr crtc = xf86_config->crtc[c];
1937821949aSmrg
1947821949aSmrg	if (!radeon_crtc_is_enabled(crtc))
1957821949aSmrg	    continue;
1967821949aSmrg
1977821949aSmrg	radeon_crtc_box(crtc, &crtc_box);
1987821949aSmrg	radeon_box_intersect(&cover_box, &crtc_box, &box);
1997821949aSmrg	coverage = radeon_box_area(&cover_box);
2007821949aSmrg	if (coverage > best_coverage ||
2017821949aSmrg	    (coverage == best_coverage && crtc == primary_crtc)) {
2027821949aSmrg	    best_crtc = crtc;
2037821949aSmrg	    best_coverage = coverage;
204de2362d3Smrg	}
205de2362d3Smrg    }
2067821949aSmrg    return best_crtc;
2077821949aSmrg}
2087821949aSmrg
2097821949aSmrg#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
2107821949aSmrgstatic xf86CrtcPtr
2117821949aSmrgradeon_covering_crtc(ScrnInfoPtr pScrn,
2127821949aSmrg		     BoxPtr	box,
2137821949aSmrg		     xf86CrtcPtr desired,
2147821949aSmrg		     BoxPtr	crtc_box_ret)
2157821949aSmrg{
2167821949aSmrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2177821949aSmrg    xf86CrtcPtr		crtc, best_crtc;
2187821949aSmrg    int			coverage, best_coverage;
2197821949aSmrg    int			c;
2207821949aSmrg    BoxRec		crtc_box, cover_box;
2210d16fef4Smrg
2227821949aSmrg    best_crtc = NULL;
2237821949aSmrg    best_coverage = 0;
2247821949aSmrg    crtc_box_ret->x1 = 0;
2257821949aSmrg    crtc_box_ret->x2 = 0;
2267821949aSmrg    crtc_box_ret->y1 = 0;
2277821949aSmrg    crtc_box_ret->y2 = 0;
2287821949aSmrg    for (c = 0; c < xf86_config->num_crtc; c++) {
2297821949aSmrg	crtc = xf86_config->crtc[c];
2307821949aSmrg	radeon_crtc_box(crtc, &crtc_box);
2317821949aSmrg	radeon_box_intersect(&cover_box, &crtc_box, box);
2327821949aSmrg	coverage = radeon_box_area(&cover_box);
2337821949aSmrg	if (coverage && crtc == desired) {
2347821949aSmrg	    *crtc_box_ret = crtc_box;
2357821949aSmrg	    return crtc;
2367821949aSmrg	} else if (coverage > best_coverage) {
2377821949aSmrg	    *crtc_box_ret = crtc_box;
2387821949aSmrg	    best_crtc = crtc;
2397821949aSmrg	    best_coverage = coverage;
2407821949aSmrg	}
2417821949aSmrg    }
242de2362d3Smrg    return best_crtc;
243de2362d3Smrg}
244de2362d3Smrg
2457821949aSmrgstatic Bool
2467821949aSmrgradeon_crtc_clip_video_helper(ScrnInfoPtr pScrn,
2477821949aSmrg			      xf86CrtcPtr *crtc_ret,
2487821949aSmrg			      xf86CrtcPtr desired_crtc,
2497821949aSmrg			      BoxPtr      dst,
2507821949aSmrg			      INT32	  *xa,
2517821949aSmrg			      INT32	  *xb,
2527821949aSmrg			      INT32	  *ya,
2537821949aSmrg			      INT32	  *yb,
2547821949aSmrg			      RegionPtr   reg,
2557821949aSmrg			      INT32	  width,
2567821949aSmrg			      INT32	  height)
2577821949aSmrg{
2587821949aSmrg    Bool	ret;
2597821949aSmrg    RegionRec	crtc_region_local;
2607821949aSmrg    RegionPtr	crtc_region = reg;
2617821949aSmrg
2627821949aSmrg    /*
2637821949aSmrg     * For overlay video, compute the relevant CRTC and
2647821949aSmrg     * clip video to that
2657821949aSmrg     */
2667821949aSmrg    if (crtc_ret) {
2677821949aSmrg	BoxRec		crtc_box;
2687821949aSmrg	xf86CrtcPtr	crtc = radeon_covering_crtc(pScrn, dst,
2697821949aSmrg						    desired_crtc,
2707821949aSmrg						    &crtc_box);
2717821949aSmrg
2727821949aSmrg	if (crtc) {
2737821949aSmrg	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
2747821949aSmrg	    crtc_region = &crtc_region_local;
2757821949aSmrg	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
2767821949aSmrg	}
2777821949aSmrg	*crtc_ret = crtc;
2787821949aSmrg    }
2797821949aSmrg
2807821949aSmrg    ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb,
2817821949aSmrg				crtc_region, width, height);
2827821949aSmrg
2837821949aSmrg    if (crtc_region != reg)
2847821949aSmrg	REGION_UNINIT (pScreen, &crtc_region_local);
2857821949aSmrg
2867821949aSmrg    return ret;
2877821949aSmrg}
2887821949aSmrg#endif
2897821949aSmrg
2907821949aSmrgstatic Bool
2917821949aSmrgradeon_crtc_clip_video(ScrnInfoPtr pScrn,
2927821949aSmrg		       xf86CrtcPtr *crtc_ret,
2937821949aSmrg		       xf86CrtcPtr desired_crtc,
2947821949aSmrg		       BoxPtr      dst,
2957821949aSmrg		       INT32       *xa,
2967821949aSmrg		       INT32       *xb,
2977821949aSmrg		       INT32       *ya,
2987821949aSmrg		       INT32       *yb,
2997821949aSmrg		       RegionPtr   reg,
3007821949aSmrg		       INT32       width,
3017821949aSmrg		       INT32       height)
3027821949aSmrg{
3037821949aSmrg#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
3047821949aSmrg    return radeon_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
3057821949aSmrg				       dst, xa, xb, ya, yb,
3067821949aSmrg				       reg, width, height);
3077821949aSmrg#else
3087821949aSmrg    return xf86_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
3097821949aSmrg				       dst, xa, xb, ya, yb,
3107821949aSmrg				       reg, width, height);
3117821949aSmrg#endif
3127821949aSmrg}
313de2362d3Smrg
314de2362d3Smrgvoid RADEONInitVideo(ScreenPtr pScreen)
315de2362d3Smrg{
316de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
317de2362d3Smrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
318de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
319de2362d3Smrg    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
3207821949aSmrg    XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
321de2362d3Smrg    int num_adaptors;
322de2362d3Smrg
323de2362d3Smrg    /* no overlay or 3D on RN50 */
324de2362d3Smrg    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2)
325de2362d3Smrg	    return;
326de2362d3Smrg
327de2362d3Smrg    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
3287821949aSmrg    newAdaptors = malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
329de2362d3Smrg    if (newAdaptors == NULL)
330de2362d3Smrg	return;
331de2362d3Smrg
332de2362d3Smrg    memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
333de2362d3Smrg    adaptors = newAdaptors;
334de2362d3Smrg
3357821949aSmrg    if (!IS_AVIVO_VARIANT && !info->kms_enabled) {
3367821949aSmrg	overlayAdaptor = RADEONSetupImageVideo(pScreen);
3377821949aSmrg	if (overlayAdaptor != NULL) {
3387821949aSmrg	    adaptors[num_adaptors++] = overlayAdaptor;
3397821949aSmrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
340de2362d3Smrg	} else
3417821949aSmrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up overlay video\n");
3427821949aSmrg	RADEONInitOffscreenImages(pScreen);
3437821949aSmrg    }
3447821949aSmrg
3457821949aSmrg    if ((info->ChipFamily < CHIP_FAMILY_RS400)
3467821949aSmrg#ifdef XF86DRI
347de2362d3Smrg	|| (info->directRenderingEnabled)
3487821949aSmrg#endif
349de2362d3Smrg	) {
350de2362d3Smrg	texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen);
351de2362d3Smrg	if (texturedAdaptor != NULL) {
352de2362d3Smrg	    adaptors[num_adaptors++] = texturedAdaptor;
353de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
354de2362d3Smrg	} else
355de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up textured video\n");
356de2362d3Smrg    } else
357de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video requires CP on R5xx/R6xx/R7xx/IGP\n");
358de2362d3Smrg
359de2362d3Smrg    if(num_adaptors)
360de2362d3Smrg	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
361de2362d3Smrg
362de2362d3Smrg    if(texturedAdaptor) {
3637821949aSmrg	XF86MCAdaptorPtr xvmcAdaptor = RADEONCreateAdaptorXvMC(pScreen, texturedAdaptor->name);
364de2362d3Smrg	if(xvmcAdaptor) {
365de2362d3Smrg	    if(!xf86XvMCScreenInit(pScreen, 1, &xvmcAdaptor))
366de2362d3Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] Failed to initialize extension.\n");
367de2362d3Smrg	    else
368de2362d3Smrg		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Extension initialized.\n");
369de2362d3Smrg	}
370de2362d3Smrg    }
371de2362d3Smrg
372de2362d3Smrg    if(newAdaptors)
373de2362d3Smrg	free(newAdaptors);
374de2362d3Smrg
375de2362d3Smrg}
376de2362d3Smrg
3777821949aSmrg/* client libraries expect an encoding */
3787821949aSmrgstatic XF86VideoEncodingRec DummyEncoding =
3797821949aSmrg{
3807821949aSmrg   0,
3817821949aSmrg   "XV_IMAGE",
3827821949aSmrg   2047, 2047,
3837821949aSmrg   {1, 1}
3847821949aSmrg};
385de2362d3Smrg
3867821949aSmrg /* the picture is interlaced - hence the half-heights */
3877821949aSmrg
3887821949aSmrgstatic XF86VideoEncodingRec
3897821949aSmrgInputVideoEncodings[] =
3907821949aSmrg{
3917821949aSmrg    { 0, "XV_IMAGE",			2047,2047,{1,1}},
3927821949aSmrg    { 1, "pal-composite",		720, 288, { 1, 50 }},
3937821949aSmrg    { 2, "pal-tuner",			720, 288, { 1, 50 }},
3947821949aSmrg    { 3, "pal-svideo",			720, 288, { 1, 50 }},
3957821949aSmrg    { 4, "ntsc-composite",		640, 240, { 1001, 60000 }},
3967821949aSmrg    { 5, "ntsc-tuner",			640, 240, { 1001, 60000 }},
3977821949aSmrg    { 6, "ntsc-svideo",			640, 240, { 1001, 60000 }},
3987821949aSmrg    { 7, "secam-composite",		720, 288, { 1, 50 }},
3997821949aSmrg    { 8, "secam-tuner",			720, 288, { 1, 50 }},
4007821949aSmrg    { 9, "secam-svideo",		720, 288, { 1, 50 }},
4017821949aSmrg    { 10,"pal_60-composite",		768, 288, { 1, 50 }},
4027821949aSmrg    { 11,"pal_60-tuner",		768, 288, { 1, 50 }},
4037821949aSmrg    { 12,"pal_60-svideo",		768, 288, { 1, 50 }}
4047821949aSmrg};
4057821949aSmrg
4067821949aSmrg
4077821949aSmrg#define NUM_FORMATS 12
4087821949aSmrg
4097821949aSmrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] =
4107821949aSmrg{
4117821949aSmrg   {8, TrueColor}, {8, DirectColor}, {8, PseudoColor},
4127821949aSmrg   {8, GrayScale}, {8, StaticGray}, {8, StaticColor},
4137821949aSmrg   {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
4147821949aSmrg   {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
4157821949aSmrg};
4167821949aSmrg
4177821949aSmrg
4187821949aSmrg#if 0
4197821949aSmrg#define NUM_ATTRIBUTES 9+6
4207821949aSmrg
4217821949aSmrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
4227821949aSmrg{
4237821949aSmrg   {XvSettable             ,     0,    1, "XV_SET_DEFAULTS"},
4247821949aSmrg   {XvSettable | XvGettable,     0,    1, "XV_AUTOPAINT_COLORKEY"},
4257821949aSmrg   {XvSettable | XvGettable,     0,   ~0, "XV_COLORKEY"},
4267821949aSmrg   {XvSettable | XvGettable,     0,    1, "XV_DOUBLE_BUFFER"},
4277821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
4287821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
4297821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
4307821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
4317821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
4327821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
4337821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
4347821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
4357821949aSmrg   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
4367821949aSmrg   {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
4377821949aSmrg   {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
4387821949aSmrg};
4397821949aSmrg
4407821949aSmrg#endif
4417821949aSmrg
4427821949aSmrg#define NUM_ATTRIBUTES 22
4437821949aSmrg#define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12)
4447821949aSmrg
4457821949aSmrgstatic XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] =
4467821949aSmrg{
4477821949aSmrg   {             XvGettable, 0, ~0, "XV_DEVICE_ID"},
4487821949aSmrg   {             XvGettable, 0, ~0, "XV_LOCATION_ID"},
4497821949aSmrg   {             XvGettable, 0, ~0, "XV_INSTANCE_ID"},
4507821949aSmrg   {XvSettable		   , 0, 1, "XV_DUMP_STATUS"},
4517821949aSmrg   {XvSettable             , 0, 1, "XV_SET_DEFAULTS"},
4527821949aSmrg   {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
4537821949aSmrg   {XvSettable | XvGettable, 0, ~0,"XV_COLORKEY"},
4547821949aSmrg   {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
4557821949aSmrg   {XvSettable | XvGettable,     0,  255, "XV_OVERLAY_ALPHA"},
4567821949aSmrg   {XvSettable | XvGettable,     0,  255, "XV_GRAPHICS_ALPHA"},
4577821949aSmrg   {XvSettable | XvGettable,     0,    1, "XV_ALPHA_MODE"},
4587821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
4597821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
4607821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
4617821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
4627821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
4637821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
4647821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
4657821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
4667821949aSmrg   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
4677821949aSmrg   {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
4687821949aSmrg   {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
4697821949aSmrg
4707821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_BRIGHTNESS"},
4717821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_CONTRAST"},
4727821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_SATURATION"},
4737821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_HUE"},
4747821949aSmrg   {XvSettable | XvGettable, 0, 2, "XV_OVERLAY_DEINTERLACING_METHOD"},
4757821949aSmrg   {XvSettable | XvGettable, 0, 12, "XV_ENCODING"},
4767821949aSmrg   {XvSettable | XvGettable, 0, -1, "XV_FREQ"},
4777821949aSmrg   {             XvGettable, -1000, 1000, "XV_TUNER_STATUS"},
4787821949aSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_VOLUME"},
4797821949aSmrg   {XvSettable | XvGettable, 0, 1, "XV_MUTE"},
4807821949aSmrg   {XvSettable | XvGettable, 0, 1, "XV_SAP"},
4817821949aSmrg   {XvSettable | XvGettable, 0, 0x1F, "XV_DEBUG_ADJUSTMENT"},
4827821949aSmrg   { 0, 0, 0, NULL}  /* just a place holder so I don't have to be fancy with commas */
4837821949aSmrg};
4847821949aSmrg
4857821949aSmrg
4867821949aSmrg#define INCLUDE_RGB_FORMATS 1
4877821949aSmrg
4887821949aSmrg#if INCLUDE_RGB_FORMATS
4897821949aSmrg
4907821949aSmrg#define NUM_IMAGES 8
4917821949aSmrg
4927821949aSmrg/* Note: GUIDs are bogus... - but nothing uses them anyway */
4937821949aSmrg
4947821949aSmrg#define FOURCC_RGBA32   0x41424752
4957821949aSmrg
4967821949aSmrg#define XVIMAGE_RGBA32(byte_order)   \
4977821949aSmrg        { \
4987821949aSmrg                FOURCC_RGBA32, \
4997821949aSmrg                XvRGB, \
5007821949aSmrg                byte_order, \
5017821949aSmrg                { 'R', 'G', 'B', 'A', \
5027821949aSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
5037821949aSmrg                32, \
5047821949aSmrg                XvPacked, \
5057821949aSmrg                1, \
5067821949aSmrg                32, 0x00FF0000, 0x0000FF00, 0x000000FF, \
5077821949aSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
5087821949aSmrg                {'A', 'R', 'G', 'B', \
5097821949aSmrg                  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}, \
5107821949aSmrg                XvTopToBottom \
5117821949aSmrg        }
5127821949aSmrg
5137821949aSmrg#define FOURCC_RGB24    0x00000000
5147821949aSmrg
5157821949aSmrg#define XVIMAGE_RGB24   \
5167821949aSmrg        { \
5177821949aSmrg                FOURCC_RGB24, \
5187821949aSmrg                XvRGB, \
5197821949aSmrg                LSBFirst, \
5207821949aSmrg                { 'R', 'G', 'B', 0, \
5217821949aSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
5227821949aSmrg                24, \
5237821949aSmrg                XvPacked, \
5247821949aSmrg                1, \
5257821949aSmrg                24, 0x00FF0000, 0x0000FF00, 0x000000FF, \
5267821949aSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
5277821949aSmrg                { 'R', 'G', 'B', \
5287821949aSmrg                  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}, \
5297821949aSmrg                XvTopToBottom \
5307821949aSmrg        }
5317821949aSmrg
5327821949aSmrg#define FOURCC_RGBT16   0x54424752
5337821949aSmrg
5347821949aSmrg#define XVIMAGE_RGBT16(byte_order)   \
5357821949aSmrg        { \
5367821949aSmrg                FOURCC_RGBT16, \
5377821949aSmrg                XvRGB, \
5387821949aSmrg                byte_order, \
5397821949aSmrg                { 'R', 'G', 'B', 'T', \
5407821949aSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
5417821949aSmrg                16, \
5427821949aSmrg                XvPacked, \
5437821949aSmrg                1, \
5447821949aSmrg                16, 0x00007C00, 0x000003E0, 0x0000001F, \
5457821949aSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
5467821949aSmrg                {'A', 'R', 'G', 'B', \
5477821949aSmrg                  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}, \
5487821949aSmrg                XvTopToBottom \
5497821949aSmrg        }
550de2362d3Smrg
5517821949aSmrg#define FOURCC_RGB16    0x32424752
5527821949aSmrg
5537821949aSmrg#define XVIMAGE_RGB16(byte_order)   \
5547821949aSmrg        { \
5557821949aSmrg                FOURCC_RGB16, \
5567821949aSmrg                XvRGB, \
5577821949aSmrg                byte_order, \
5587821949aSmrg                { 'R', 'G', 'B', 0x00, \
5597821949aSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
5607821949aSmrg                16, \
5617821949aSmrg                XvPacked, \
5627821949aSmrg                1, \
5637821949aSmrg                16, 0x0000F800, 0x000007E0, 0x0000001F, \
5647821949aSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
5657821949aSmrg                {'R', 'G', 'B', \
5667821949aSmrg                  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}, \
5677821949aSmrg                XvTopToBottom \
5687821949aSmrg        }
5697821949aSmrg
5707821949aSmrgstatic XF86ImageRec Images[NUM_IMAGES] =
5717821949aSmrg{
572de2362d3Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
5737821949aSmrg        XVIMAGE_RGBA32(MSBFirst),
5747821949aSmrg        XVIMAGE_RGBT16(MSBFirst),
5757821949aSmrg        XVIMAGE_RGB16(MSBFirst),
5767821949aSmrg#else
5777821949aSmrg        XVIMAGE_RGBA32(LSBFirst),
5787821949aSmrg        XVIMAGE_RGBT16(LSBFirst),
5797821949aSmrg        XVIMAGE_RGB16(LSBFirst),
580de2362d3Smrg#endif
5817821949aSmrg        XVIMAGE_RGB24,
5827821949aSmrg        XVIMAGE_YUY2,
5837821949aSmrg        XVIMAGE_UYVY,
5847821949aSmrg        XVIMAGE_YV12,
5857821949aSmrg        XVIMAGE_I420
5867821949aSmrg};
587de2362d3Smrg
5887821949aSmrg#else
589de2362d3Smrg
5907821949aSmrg#define NUM_IMAGES 4
5917821949aSmrg
5927821949aSmrgstatic XF86ImageRec Images[NUM_IMAGES] =
5937821949aSmrg{
5947821949aSmrg    XVIMAGE_YUY2,
5957821949aSmrg    XVIMAGE_UYVY,
5967821949aSmrg    XVIMAGE_YV12,
5977821949aSmrg    XVIMAGE_I420
5987821949aSmrg};
5997821949aSmrg
6007821949aSmrg#endif
6017821949aSmrg
6027821949aSmrg/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
6037821949aSmrgstatic REF_TRANSFORM trans[2] =
6047821949aSmrg{
6057821949aSmrg    {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
6067821949aSmrg    {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0}  /* BT.709 */
6077821949aSmrg};
6087821949aSmrg
6097821949aSmrg/* Gamma curve definition for preset gammas */
6107821949aSmrgtypedef struct tagGAMMA_CURVE_R100
6117821949aSmrg{
6127821949aSmrg    uint32_t GAMMA_0_F_SLOPE;
6137821949aSmrg    uint32_t GAMMA_0_F_OFFSET;
6147821949aSmrg    uint32_t GAMMA_10_1F_SLOPE;
6157821949aSmrg    uint32_t GAMMA_10_1F_OFFSET;
6167821949aSmrg    uint32_t GAMMA_20_3F_SLOPE;
6177821949aSmrg    uint32_t GAMMA_20_3F_OFFSET;
6187821949aSmrg    uint32_t GAMMA_40_7F_SLOPE;
6197821949aSmrg    uint32_t GAMMA_40_7F_OFFSET;
6207821949aSmrg    uint32_t GAMMA_380_3BF_SLOPE;
6217821949aSmrg    uint32_t GAMMA_380_3BF_OFFSET;
6227821949aSmrg    uint32_t GAMMA_3C0_3FF_SLOPE;
6237821949aSmrg    uint32_t GAMMA_3C0_3FF_OFFSET;
6247821949aSmrg    float OvGammaCont;
6257821949aSmrg} GAMMA_CURVE_R100;
6267821949aSmrg
6277821949aSmrgtypedef struct tagGAMMA_CURVE_R200
6287821949aSmrg{
6297821949aSmrg    uint32_t GAMMA_0_F_SLOPE;
6307821949aSmrg    uint32_t GAMMA_0_F_OFFSET;
6317821949aSmrg    uint32_t GAMMA_10_1F_SLOPE;
6327821949aSmrg    uint32_t GAMMA_10_1F_OFFSET;
6337821949aSmrg    uint32_t GAMMA_20_3F_SLOPE;
6347821949aSmrg    uint32_t GAMMA_20_3F_OFFSET;
6357821949aSmrg    uint32_t GAMMA_40_7F_SLOPE;
6367821949aSmrg    uint32_t GAMMA_40_7F_OFFSET;
6377821949aSmrg    uint32_t GAMMA_80_BF_SLOPE;
6387821949aSmrg    uint32_t GAMMA_80_BF_OFFSET;
6397821949aSmrg    uint32_t GAMMA_C0_FF_SLOPE;
6407821949aSmrg    uint32_t GAMMA_C0_FF_OFFSET;
6417821949aSmrg    uint32_t GAMMA_100_13F_SLOPE;
6427821949aSmrg    uint32_t GAMMA_100_13F_OFFSET;
6437821949aSmrg    uint32_t GAMMA_140_17F_SLOPE;
6447821949aSmrg    uint32_t GAMMA_140_17F_OFFSET;
6457821949aSmrg    uint32_t GAMMA_180_1BF_SLOPE;
6467821949aSmrg    uint32_t GAMMA_180_1BF_OFFSET;
6477821949aSmrg    uint32_t GAMMA_1C0_1FF_SLOPE;
6487821949aSmrg    uint32_t GAMMA_1C0_1FF_OFFSET;
6497821949aSmrg    uint32_t GAMMA_200_23F_SLOPE;
6507821949aSmrg    uint32_t GAMMA_200_23F_OFFSET;
6517821949aSmrg    uint32_t GAMMA_240_27F_SLOPE;
6527821949aSmrg    uint32_t GAMMA_240_27F_OFFSET;
6537821949aSmrg    uint32_t GAMMA_280_2BF_SLOPE;
6547821949aSmrg    uint32_t GAMMA_280_2BF_OFFSET;
6557821949aSmrg    uint32_t GAMMA_2C0_2FF_SLOPE;
6567821949aSmrg    uint32_t GAMMA_2C0_2FF_OFFSET;
6577821949aSmrg    uint32_t GAMMA_300_33F_SLOPE;
6587821949aSmrg    uint32_t GAMMA_300_33F_OFFSET;
6597821949aSmrg    uint32_t GAMMA_340_37F_SLOPE;
6607821949aSmrg    uint32_t GAMMA_340_37F_OFFSET;
6617821949aSmrg    uint32_t GAMMA_380_3BF_SLOPE;
6627821949aSmrg    uint32_t GAMMA_380_3BF_OFFSET;
6637821949aSmrg    uint32_t GAMMA_3C0_3FF_SLOPE;
6647821949aSmrg    uint32_t GAMMA_3C0_3FF_OFFSET;
6657821949aSmrg    float OvGammaCont;
6667821949aSmrg} GAMMA_CURVE_R200;
6677821949aSmrg
6687821949aSmrg
6697821949aSmrg/* Preset gammas */
6707821949aSmrgstatic GAMMA_CURVE_R100 gamma_curve_r100[8] =
6717821949aSmrg{
6727821949aSmrg	/* Gamma 1.0 */
6737821949aSmrg	{0x100, 0x0,
6747821949aSmrg	 0x100, 0x20,
6757821949aSmrg	 0x100, 0x40,
6767821949aSmrg	 0x100, 0x80,
6777821949aSmrg	 0x100, 0x100,
6787821949aSmrg	 0x100, 0x100,
6797821949aSmrg	 1.0},
6807821949aSmrg	/* Gamma 0.85 */
6817821949aSmrg	{0x75,  0x0,
6827821949aSmrg	 0xA2,  0xF,
6837821949aSmrg	 0xAC,  0x23,
6847821949aSmrg	 0xC6,  0x4E,
6857821949aSmrg	 0x129, 0xD6,
6867821949aSmrg	 0x12B, 0xD5,
6877821949aSmrg	 1.0},
6887821949aSmrg	/* Gamma 1.1 */
6897821949aSmrg	{0x180, 0x0,
6907821949aSmrg	 0x13C, 0x30,
6917821949aSmrg	 0x13C, 0x57,
6927821949aSmrg	 0x123, 0xA5,
6937821949aSmrg	 0xEA,  0x116,
6947821949aSmrg	 0xEA, 0x116,
6957821949aSmrg	 0.9913},
6967821949aSmrg	/* Gamma 1.2 */
6977821949aSmrg	{0x21B, 0x0,
6987821949aSmrg	 0x16D, 0x43,
6997821949aSmrg	 0x172, 0x71,
7007821949aSmrg	 0x13D, 0xCD,
7017821949aSmrg	 0xD9,  0x128,
7027821949aSmrg	 0xD6, 0x12A,
7037821949aSmrg	 0.9827},
7047821949aSmrg	/* Gamma 1.45 */
7057821949aSmrg	{0x404, 0x0,
7067821949aSmrg	 0x1B9, 0x81,
7077821949aSmrg	 0x1EE, 0xB8,
7087821949aSmrg	 0x16A, 0x133,
7097821949aSmrg	 0xB7, 0x14B,
7107821949aSmrg	 0xB2, 0x14E,
7117821949aSmrg	 0.9567},
7127821949aSmrg	/* Gamma 1.7 */
7137821949aSmrg	{0x658, 0x0,
7147821949aSmrg	 0x1B5, 0xCB,
7157821949aSmrg	 0x25F, 0x102,
7167821949aSmrg	 0x181, 0x199,
7177821949aSmrg	 0x9C,  0x165,
7187821949aSmrg	 0x98, 0x167,
7197821949aSmrg	 0.9394},
7207821949aSmrg	/* Gamma 2.2 */
7217821949aSmrg	{0x7FF, 0x0,
7227821949aSmrg	 0x625, 0x100,
7237821949aSmrg	 0x1E4, 0x1C4,
7247821949aSmrg	 0x1BD, 0x23D,
7257821949aSmrg	 0x79,  0x187,
7267821949aSmrg	 0x76,  0x188,
7277821949aSmrg	 0.9135},
7287821949aSmrg	/* Gamma 2.5 */
7297821949aSmrg	{0x7FF, 0x0,
7307821949aSmrg	 0x7FF, 0x100,
7317821949aSmrg	 0x2AD, 0x200,
7327821949aSmrg	 0x1A2, 0x2AB,
7337821949aSmrg	 0x6E,  0x194,
7347821949aSmrg	 0x67,  0x197,
7357821949aSmrg	 0.9135}
7367821949aSmrg};
7377821949aSmrg
7387821949aSmrgstatic GAMMA_CURVE_R200 gamma_curve_r200[8] =
7397821949aSmrg {
7407821949aSmrg	/* Gamma 1.0 */
7417821949aSmrg      {0x00000100, 0x00000000,
7427821949aSmrg       0x00000100, 0x00000020,
7437821949aSmrg       0x00000100, 0x00000040,
7447821949aSmrg       0x00000100, 0x00000080,
7457821949aSmrg       0x00000100, 0x00000100,
7467821949aSmrg       0x00000100, 0x00000100,
7477821949aSmrg       0x00000100, 0x00000200,
7487821949aSmrg       0x00000100, 0x00000200,
7497821949aSmrg       0x00000100, 0x00000300,
7507821949aSmrg       0x00000100, 0x00000300,
7517821949aSmrg       0x00000100, 0x00000400,
7527821949aSmrg       0x00000100, 0x00000400,
7537821949aSmrg       0x00000100, 0x00000500,
7547821949aSmrg       0x00000100, 0x00000500,
7557821949aSmrg       0x00000100, 0x00000600,
7567821949aSmrg       0x00000100, 0x00000600,
7577821949aSmrg       0x00000100, 0x00000700,
7587821949aSmrg       0x00000100, 0x00000700,
7597821949aSmrg       1.0},
7607821949aSmrg	/* Gamma 0.85 */
7617821949aSmrg      {0x0000001D, 0x00000000,
7627821949aSmrg       0x00000028, 0x0000000F,
7637821949aSmrg       0x00000056, 0x00000023,
7647821949aSmrg       0x000000C5, 0x0000004E,
7657821949aSmrg       0x000000DA, 0x000000B0,
7667821949aSmrg       0x000000E6, 0x000000AA,
7677821949aSmrg       0x000000F1, 0x00000190,
7687821949aSmrg       0x000000F9, 0x0000018C,
7697821949aSmrg       0x00000101, 0x00000286,
7707821949aSmrg       0x00000108, 0x00000282,
7717821949aSmrg       0x0000010D, 0x0000038A,
7727821949aSmrg       0x00000113, 0x00000387,
7737821949aSmrg       0x00000118, 0x0000049A,
7747821949aSmrg       0x0000011C, 0x00000498,
7757821949aSmrg       0x00000120, 0x000005B4,
7767821949aSmrg       0x00000124, 0x000005B2,
7777821949aSmrg       0x00000128, 0x000006D6,
7787821949aSmrg       0x0000012C, 0x000006D5,
7797821949aSmrg       1.0},
7807821949aSmrg	/* Gamma 1.1 */
7817821949aSmrg      {0x00000060, 0x00000000,
7827821949aSmrg       0x0000004F, 0x00000030,
7837821949aSmrg       0x0000009C, 0x00000057,
7847821949aSmrg       0x00000121, 0x000000A5,
7857821949aSmrg       0x00000113, 0x00000136,
7867821949aSmrg       0x0000010B, 0x0000013A,
7877821949aSmrg       0x00000105, 0x00000245,
7887821949aSmrg       0x00000100, 0x00000247,
7897821949aSmrg       0x000000FD, 0x00000348,
7907821949aSmrg       0x000000F9, 0x00000349,
7917821949aSmrg       0x000000F6, 0x00000443,
7927821949aSmrg       0x000000F4, 0x00000444,
7937821949aSmrg       0x000000F2, 0x00000538,
7947821949aSmrg       0x000000F0, 0x00000539,
7957821949aSmrg       0x000000EE, 0x00000629,
7967821949aSmrg       0x000000EC, 0x00000629,
7977821949aSmrg       0x000000EB, 0x00000716,
7987821949aSmrg       0x000000E9, 0x00000717,
7997821949aSmrg       0.9913},
8007821949aSmrg	/* Gamma 1.2 */
8017821949aSmrg      {0x00000087, 0x00000000,
8027821949aSmrg       0x0000005B, 0x00000043,
8037821949aSmrg       0x000000B7, 0x00000071,
8047821949aSmrg       0x0000013D, 0x000000CD,
8057821949aSmrg       0x00000121, 0x0000016B,
8067821949aSmrg       0x00000113, 0x00000172,
8077821949aSmrg       0x00000107, 0x00000286,
8087821949aSmrg       0x000000FF, 0x0000028A,
8097821949aSmrg       0x000000F8, 0x00000389,
8107821949aSmrg       0x000000F2, 0x0000038B,
8117821949aSmrg       0x000000ED, 0x0000047D,
8127821949aSmrg       0x000000E9, 0x00000480,
8137821949aSmrg       0x000000E5, 0x00000568,
8147821949aSmrg       0x000000E1, 0x0000056A,
8157821949aSmrg       0x000000DE, 0x0000064B,
8167821949aSmrg       0x000000DB, 0x0000064D,
8177821949aSmrg       0x000000D9, 0x00000728,
8187821949aSmrg       0x000000D6, 0x00000729,
8197821949aSmrg       0.9827},
8207821949aSmrg	/* Gamma 1.45 */
8217821949aSmrg      {0x00000101, 0x00000000,
8227821949aSmrg       0x0000006E, 0x00000081,
8237821949aSmrg       0x000000F7, 0x000000B8,
8247821949aSmrg       0x0000016E, 0x00000133,
8257821949aSmrg       0x00000139, 0x000001EA,
8267821949aSmrg       0x0000011B, 0x000001F9,
8277821949aSmrg       0x00000105, 0x00000314,
8287821949aSmrg       0x000000F6, 0x0000031C,
8297821949aSmrg       0x000000E9, 0x00000411,
8307821949aSmrg       0x000000DF, 0x00000417,
8317821949aSmrg       0x000000D7, 0x000004F6,
8327821949aSmrg       0x000000CF, 0x000004F9,
8337821949aSmrg       0x000000C9, 0x000005C9,
8347821949aSmrg       0x000000C4, 0x000005CC,
8357821949aSmrg       0x000000BF, 0x0000068F,
8367821949aSmrg       0x000000BA, 0x00000691,
8377821949aSmrg       0x000000B6, 0x0000074B,
8387821949aSmrg       0x000000B2, 0x0000074D,
8397821949aSmrg       0.9567},
8407821949aSmrg	/* Gamma 1.7 */
8417821949aSmrg      {0x00000196, 0x00000000,
8427821949aSmrg       0x0000006D, 0x000000CB,
8437821949aSmrg       0x0000012F, 0x00000102,
8447821949aSmrg       0x00000187, 0x00000199,
8457821949aSmrg       0x00000144, 0x0000025b,
8467821949aSmrg       0x00000118, 0x00000273,
8477821949aSmrg       0x000000FE, 0x0000038B,
8487821949aSmrg       0x000000E9, 0x00000395,
8497821949aSmrg       0x000000DA, 0x0000047E,
8507821949aSmrg       0x000000CE, 0x00000485,
8517821949aSmrg       0x000000C3, 0x00000552,
8527821949aSmrg       0x000000BB, 0x00000556,
8537821949aSmrg       0x000000B3, 0x00000611,
8547821949aSmrg       0x000000AC, 0x00000614,
8557821949aSmrg       0x000000A7, 0x000006C1,
8567821949aSmrg       0x000000A1, 0x000006C3,
8577821949aSmrg       0x0000009D, 0x00000765,
8587821949aSmrg       0x00000098, 0x00000767,
8597821949aSmrg       0.9394},
8607821949aSmrg	/* Gamma 2.2 */
8617821949aSmrg      {0x000001FF, 0x00000000,
8627821949aSmrg       0x0000018A, 0x00000100,
8637821949aSmrg       0x000000F1, 0x000001C5,
8647821949aSmrg       0x000001D6, 0x0000023D,
8657821949aSmrg       0x00000124, 0x00000328,
8667821949aSmrg       0x00000116, 0x0000032F,
8677821949aSmrg       0x000000E2, 0x00000446,
8687821949aSmrg       0x000000D3, 0x0000044D,
8697821949aSmrg       0x000000BC, 0x00000520,
8707821949aSmrg       0x000000B0, 0x00000526,
8717821949aSmrg       0x000000A4, 0x000005D6,
8727821949aSmrg       0x0000009B, 0x000005DB,
8737821949aSmrg       0x00000092, 0x00000676,
8747821949aSmrg       0x0000008B, 0x00000679,
8757821949aSmrg       0x00000085, 0x00000704,
8767821949aSmrg       0x00000080, 0x00000707,
8777821949aSmrg       0x0000007B, 0x00000787,
8787821949aSmrg       0x00000076, 0x00000789,
8797821949aSmrg       0.9135},
8807821949aSmrg	/* Gamma 2.5 */
8817821949aSmrg      {0x000001FF, 0x00000000,
8827821949aSmrg       0x000001FF, 0x00000100,
8837821949aSmrg       0x00000159, 0x000001FF,
8847821949aSmrg       0x000001AC, 0x000002AB,
8857821949aSmrg       0x0000012F, 0x00000381,
8867821949aSmrg       0x00000101, 0x00000399,
8877821949aSmrg       0x000000D9, 0x0000049A,
8887821949aSmrg       0x000000C3, 0x000004A5,
8897821949aSmrg       0x000000AF, 0x00000567,
8907821949aSmrg       0x000000A1, 0x0000056E,
8917821949aSmrg       0x00000095, 0x00000610,
8927821949aSmrg       0x0000008C, 0x00000614,
8937821949aSmrg       0x00000084, 0x000006A0,
8947821949aSmrg       0x0000007D, 0x000006A4,
8957821949aSmrg       0x00000077, 0x00000721,
8967821949aSmrg       0x00000071, 0x00000723,
8977821949aSmrg       0x0000006D, 0x00000795,
8987821949aSmrg       0x00000068, 0x00000797,
8997821949aSmrg       0.9135}
9007821949aSmrg};
9017821949aSmrg
9027821949aSmrgstatic void
9037821949aSmrgRADEONSetOverlayGamma(ScrnInfoPtr pScrn, uint32_t gamma)
9047821949aSmrg{
9057821949aSmrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
9067821949aSmrg    unsigned char   *RADEONMMIO = info->MMIO;
9077821949aSmrg
9087821949aSmrg    /* Set gamma */
9097821949aSmrg    RADEONWaitForIdleMMIO(pScrn);
9107821949aSmrg
9117821949aSmrg    if (info->ChipFamily < CHIP_FAMILY_R200) {
9127821949aSmrg	uint32_t ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL) & ~RADEON_SCALER_GAMMA_SEL_MASK;
9137821949aSmrg	OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 5));
9147821949aSmrg    }
9157821949aSmrg
9167821949aSmrg    /* Load gamma curve adjustments */
9177821949aSmrg    if (info->ChipFamily >= CHIP_FAMILY_R200) {
9187821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_000_00F,
9197821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
9207821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010));
9217821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_010_01F,
9227821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
9237821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
9247821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_020_03F,
9257821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
9267821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
9277821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_040_07F,
9287821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
9297821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
9307821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_080_0BF,
9317821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_80_BF_OFFSET << 0x00000000) |
9327821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_80_BF_SLOPE << 0x00000010));
9337821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_0C0_0FF,
9347821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_C0_FF_OFFSET << 0x00000000) |
9357821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_C0_FF_SLOPE << 0x00000010));
9367821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_100_13F,
9377821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_100_13F_OFFSET << 0x00000000) |
9387821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_100_13F_SLOPE << 0x00000010));
9397821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_140_17F,
9407821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_140_17F_OFFSET << 0x00000000) |
9417821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_140_17F_SLOPE << 0x00000010));
9427821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_180_1BF,
9437821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_180_1BF_OFFSET << 0x00000000) |
9447821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_180_1BF_SLOPE << 0x00000010));
9457821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_1C0_1FF,
9467821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_OFFSET << 0x00000000) |
9477821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_SLOPE << 0x00000010));
9487821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_200_23F,
9497821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_200_23F_OFFSET << 0x00000000) |
9507821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_200_23F_SLOPE << 0x00000010));
9517821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_240_27F,
9527821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_240_27F_OFFSET << 0x00000000) |
9537821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_240_27F_SLOPE << 0x00000010));
9547821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_280_2BF,
9557821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_280_2BF_OFFSET << 0x00000000) |
9567821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_280_2BF_SLOPE << 0x00000010));
9577821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_2C0_2FF,
9587821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_OFFSET << 0x00000000) |
9597821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_SLOPE << 0x00000010));
9607821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_300_33F,
9617821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_300_33F_OFFSET << 0x00000000) |
9627821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_300_33F_SLOPE << 0x00000010));
9637821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_340_37F,
9647821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_340_37F_OFFSET << 0x00000000) |
9657821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_340_37F_SLOPE << 0x00000010));
9667821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_380_3BF,
9677821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
9687821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
9697821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
9707821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
9717821949aSmrg	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
9727821949aSmrg    } else {
9737821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_000_00F,
9747821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
9757821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_0_F_SLOPE << 0x00000010));
9767821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_010_01F,
9777821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
9787821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
9797821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_020_03F,
9807821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
9817821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
9827821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_040_07F,
9837821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
9847821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
9857821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_380_3BF,
9867821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
9877821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
9887821949aSmrg    	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
9897821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
9907821949aSmrg	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
9917821949aSmrg    }
9927821949aSmrg
9937821949aSmrg}
9947821949aSmrg
9957821949aSmrgstatic uint32_t
9967821949aSmrgRADEONTranslateUserGamma(uint32_t user_gamma)
9977821949aSmrg{
9987821949aSmrg    /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
9997821949aSmrg    if (user_gamma <= 925)       /* 0.85 */
10007821949aSmrg	return 1;
10017821949aSmrg    else if (user_gamma <= 1050) /* 1.0  */
10027821949aSmrg	return 0;
10037821949aSmrg    else if (user_gamma <= 1150) /* 1.1  */
10047821949aSmrg	return 2;
10057821949aSmrg    else if (user_gamma <= 1325) /* 1.2  */
10067821949aSmrg	return 3;
10077821949aSmrg    else if (user_gamma <= 1575) /* 1.45 */
10087821949aSmrg	return 4;
10097821949aSmrg    else if (user_gamma <= 1950) /* 1.7  */
10107821949aSmrg	return 5;
10117821949aSmrg    else if (user_gamma <= 2350) /* 2.2  */
10127821949aSmrg	return 6;
10137821949aSmrg    else if (user_gamma > 2350)  /* 2.5  */
10147821949aSmrg	return 7;
10157821949aSmrg    else
10167821949aSmrg	return 0;
10177821949aSmrg}
10187821949aSmrg
10197821949aSmrg
10207821949aSmrg/****************************************************************************
10217821949aSmrg * SetTransform                                                             *
10227821949aSmrg *  Function: Calculates and sets color space transform from supplied       *
10237821949aSmrg *            reference transform, gamma, brightness, contrast, hue and     *
10247821949aSmrg *            saturation.                                                   *
10257821949aSmrg *    Inputs: bright - brightness                                           *
10267821949aSmrg *            cont - contrast                                               *
10277821949aSmrg *            sat - saturation                                              *
10287821949aSmrg *            hue - hue                                                     *
10297821949aSmrg *            red_intensity - intensity of red component                    *
10307821949aSmrg *            green_intensity - intensity of green component                *
10317821949aSmrg *            blue_intensity - intensity of blue component                  *
10327821949aSmrg *            ref - index to the table of refernce transforms               *
10337821949aSmrg *            user_gamma - gamma value x 1000 (e.g., 1200 = gamma of 1.2)   *
10347821949aSmrg *   Outputs: NONE                                                          *
10357821949aSmrg ****************************************************************************/
10367821949aSmrg
10377821949aSmrgstatic void RADEONSetTransform (ScrnInfoPtr pScrn,
10387821949aSmrg				float	    bright,
10397821949aSmrg				float	    cont,
10407821949aSmrg				float	    sat,
10417821949aSmrg				float	    hue,
10427821949aSmrg				float	    red_intensity,
10437821949aSmrg				float	    green_intensity,
10447821949aSmrg				float	    blue_intensity,
10457821949aSmrg				uint32_t    ref,
10467821949aSmrg				uint32_t    user_gamma)
10477821949aSmrg{
10487821949aSmrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
10497821949aSmrg    unsigned char   *RADEONMMIO = info->MMIO;
10507821949aSmrg    float	    OvHueSin, OvHueCos;
10517821949aSmrg    float	    CAdjLuma, CAdjOff;
10527821949aSmrg    float	    CAdjRCb, CAdjRCr;
10537821949aSmrg    float	    CAdjGCb, CAdjGCr;
10547821949aSmrg    float	    CAdjBCb, CAdjBCr;
10557821949aSmrg    float	    RedAdj,GreenAdj,BlueAdj;
10567821949aSmrg    float	    OvLuma, OvROff, OvGOff, OvBOff;
10577821949aSmrg    float	    OvRCb, OvRCr;
10587821949aSmrg    float	    OvGCb, OvGCr;
10597821949aSmrg    float	    OvBCb, OvBCr;
10607821949aSmrg    float	    Loff = 64.0;
10617821949aSmrg    float	    Coff = 512.0f;
10627821949aSmrg
10637821949aSmrg    uint32_t	    dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff;
10647821949aSmrg    uint32_t	    dwOvRCb, dwOvRCr;
10657821949aSmrg    uint32_t	    dwOvGCb, dwOvGCr;
10667821949aSmrg    uint32_t	    dwOvBCb, dwOvBCr;
10677821949aSmrg    uint32_t	    gamma = 0;
10687821949aSmrg
10697821949aSmrg    if (ref >= 2)
10707821949aSmrg	return;
10717821949aSmrg
10727821949aSmrg    /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
10737821949aSmrg    gamma = RADEONTranslateUserGamma(user_gamma);
10747821949aSmrg
10757821949aSmrg    if (gamma >= 8)
10767821949aSmrg	return;
10777821949aSmrg
10787821949aSmrg    OvHueSin = sin(hue);
10797821949aSmrg    OvHueCos = cos(hue);
10807821949aSmrg
10817821949aSmrg    CAdjLuma = cont * trans[ref].RefLuma;
10827821949aSmrg    CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0;
10837821949aSmrg    RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0;
10847821949aSmrg    GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0;
10857821949aSmrg    BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0;
10867821949aSmrg
10877821949aSmrg    CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr;
10887821949aSmrg    CAdjRCr = sat * OvHueCos * trans[ref].RefRCr;
10897821949aSmrg    CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr);
10907821949aSmrg    CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr);
10917821949aSmrg    CAdjBCb = sat * OvHueCos * trans[ref].RefBCb;
10927821949aSmrg    CAdjBCr = sat * OvHueSin * trans[ref].RefBCb;
10937821949aSmrg
10947821949aSmrg#if 0 /* default constants */
10957821949aSmrg    CAdjLuma = 1.16455078125;
10967821949aSmrg
10977821949aSmrg    CAdjRCb = 0.0;
10987821949aSmrg    CAdjRCr = 1.59619140625;
10997821949aSmrg    CAdjGCb = -0.39111328125;
11007821949aSmrg    CAdjGCr = -0.8125;
11017821949aSmrg    CAdjBCb = 2.01708984375;
11027821949aSmrg    CAdjBCr = 0;
11037821949aSmrg#endif
11047821949aSmrg
11057821949aSmrg    OvLuma = CAdjLuma * gamma_curve_r100[gamma].OvGammaCont;
11067821949aSmrg    OvRCb = CAdjRCb * gamma_curve_r100[gamma].OvGammaCont;
11077821949aSmrg    OvRCr = CAdjRCr * gamma_curve_r100[gamma].OvGammaCont;
11087821949aSmrg    OvGCb = CAdjGCb * gamma_curve_r100[gamma].OvGammaCont;
11097821949aSmrg    OvGCr = CAdjGCr * gamma_curve_r100[gamma].OvGammaCont;
11107821949aSmrg    OvBCb = CAdjBCb * gamma_curve_r100[gamma].OvGammaCont;
11117821949aSmrg    OvBCr = CAdjBCr * gamma_curve_r100[gamma].OvGammaCont;
11127821949aSmrg    OvROff = RedAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
11137821949aSmrg	OvLuma * Loff - (OvRCb + OvRCr) * Coff;
11147821949aSmrg    OvGOff = GreenAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
11157821949aSmrg	OvLuma * Loff - (OvGCb + OvGCr) * Coff;
11167821949aSmrg    OvBOff = BlueAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
11177821949aSmrg	OvLuma * Loff - (OvBCb + OvBCr) * Coff;
11187821949aSmrg#if 0 /* default constants */
11197821949aSmrg    OvROff = -888.5;
11207821949aSmrg    OvGOff = 545;
11217821949aSmrg    OvBOff = -1104;
11227821949aSmrg#endif
11237821949aSmrg
11247821949aSmrg    OvROff = ClipValue(OvROff, -2048.0, 2047.5);
11257821949aSmrg    OvGOff = ClipValue(OvGOff, -2048.0, 2047.5);
11267821949aSmrg    OvBOff = ClipValue(OvBOff, -2048.0, 2047.5);
11277821949aSmrg    dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff;
11287821949aSmrg    dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff;
11297821949aSmrg    dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff;
11307821949aSmrg
11317821949aSmrg    if(info->ChipFamily == CHIP_FAMILY_RADEON)
11327821949aSmrg    {
11337821949aSmrg	dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17;
11347821949aSmrg	dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1;
11357821949aSmrg	dwOvRCr = (((INT32)(OvRCr * 2048.0))&0x7fff)<<17;
11367821949aSmrg	dwOvGCb = (((INT32)(OvGCb * 2048.0))&0x7fff)<<1;
11377821949aSmrg	dwOvGCr = (((INT32)(OvGCr * 2048.0))&0x7fff)<<17;
11387821949aSmrg	dwOvBCb = (((INT32)(OvBCb * 2048.0))&0x7fff)<<1;
11397821949aSmrg	dwOvBCr = (((INT32)(OvBCr * 2048.0))&0x7fff)<<17;
11407821949aSmrg    }
11417821949aSmrg    else
11427821949aSmrg    {
11437821949aSmrg	dwOvLuma = (((INT32)(OvLuma * 256.0))&0xfff)<<20;
11447821949aSmrg	dwOvRCb = (((INT32)(OvRCb * 256.0))&0xfff)<<4;
11457821949aSmrg	dwOvRCr = (((INT32)(OvRCr * 256.0))&0xfff)<<20;
11467821949aSmrg	dwOvGCb = (((INT32)(OvGCb * 256.0))&0xfff)<<4;
11477821949aSmrg	dwOvGCr = (((INT32)(OvGCr * 256.0))&0xfff)<<20;
11487821949aSmrg	dwOvBCb = (((INT32)(OvBCb * 256.0))&0xfff)<<4;
11497821949aSmrg	dwOvBCr = (((INT32)(OvBCr * 256.0))&0xfff)<<20;
11507821949aSmrg    }
11517821949aSmrg
11527821949aSmrg    /* set gamma */
11537821949aSmrg    RADEONSetOverlayGamma(pScrn, gamma);
11547821949aSmrg
11557821949aSmrg    /* color transforms */
11567821949aSmrg    OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma);
11577821949aSmrg    OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr);
11587821949aSmrg    OUTREG(RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma);
11597821949aSmrg    OUTREG(RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr);
11607821949aSmrg    OUTREG(RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma);
11617821949aSmrg    OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr);
11627821949aSmrg}
11637821949aSmrg
11647821949aSmrgstatic void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode)
11657821949aSmrg{
11667821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
11677821949aSmrg    unsigned char *RADEONMMIO = info->MMIO;
11687821949aSmrg
11697821949aSmrg    if (alpha_mode == 0) { /* key mode */
11707821949aSmrg    	OUTREG(RADEON_OV0_KEY_CNTL,
11717821949aSmrg		RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */
11727821949aSmrg		RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */
11737821949aSmrg		RADEON_CMP_MIX_OR);
11747821949aSmrg    	/* crtc 1 */
11757821949aSmrg    	OUTREG(RADEON_DISP_MERGE_CNTL,
11767821949aSmrg		(RADEON_DISP_ALPHA_MODE_KEY &
11777821949aSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
11787821949aSmrg		((gr_alpha << 0x00000010) &
11797821949aSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
11807821949aSmrg		((ov_alpha << 0x00000018) &
11817821949aSmrg		RADEON_DISP_OV0_ALPHA_MASK));
11827821949aSmrg    	/* crtc 2 */
11837821949aSmrg    	OUTREG(RADEON_DISP2_MERGE_CNTL,
11847821949aSmrg		(RADEON_DISP_ALPHA_MODE_KEY &
11857821949aSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
11867821949aSmrg		((gr_alpha << 0x00000010) &
11877821949aSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
11887821949aSmrg		((ov_alpha << 0x00000018) &
11897821949aSmrg		RADEON_DISP_OV0_ALPHA_MASK));
11907821949aSmrg    } else { /* global mode */
11917821949aSmrg    	OUTREG(RADEON_OV0_KEY_CNTL,
11927821949aSmrg		RADEON_GRAPHIC_KEY_FN_FALSE |   /* what does this do? */
11937821949aSmrg		RADEON_VIDEO_KEY_FN_FALSE |   /* what does this do? */
11947821949aSmrg		RADEON_CMP_MIX_AND);
11957821949aSmrg    	/* crtc 2 */
11967821949aSmrg    	OUTREG(RADEON_DISP2_MERGE_CNTL,
11977821949aSmrg		(RADEON_DISP_ALPHA_MODE_GLOBAL &
11987821949aSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
11997821949aSmrg		((gr_alpha << 0x00000010) &
12007821949aSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
12017821949aSmrg		((ov_alpha << 0x00000018) &
12027821949aSmrg		RADEON_DISP_OV0_ALPHA_MASK));
12037821949aSmrg    	/* crtc 1 */
12047821949aSmrg    	OUTREG(RADEON_DISP_MERGE_CNTL,
12057821949aSmrg		(RADEON_DISP_ALPHA_MODE_GLOBAL &
12067821949aSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
12077821949aSmrg		((gr_alpha << 0x00000010) &
12087821949aSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
12097821949aSmrg		((ov_alpha << 0x00000018) &
12107821949aSmrg		RADEON_DISP_OV0_ALPHA_MASK));
1211de2362d3Smrg    }
12127821949aSmrg     /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */
12137821949aSmrg     /* not yet supported */
1214de2362d3Smrg}
1215de2362d3Smrg
12167821949aSmrgstatic void RADEONSetColorKey(ScrnInfoPtr pScrn, uint32_t colorKey)
12177821949aSmrg{
12187821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
12197821949aSmrg    unsigned char *RADEONMMIO = info->MMIO;
12207821949aSmrg    uint32_t min, max;
12217821949aSmrg    uint8_t r, g, b;
12227821949aSmrg
12237821949aSmrg    if (info->CurrentLayout.depth > 8)
12247821949aSmrg    {
12257821949aSmrg	uint32_t	rbits, gbits, bbits;
12267821949aSmrg
12277821949aSmrg	rbits = (colorKey & pScrn->mask.red) >> pScrn->offset.red;
12287821949aSmrg	gbits = (colorKey & pScrn->mask.green) >> pScrn->offset.green;
12297821949aSmrg	bbits = (colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
12307821949aSmrg
12317821949aSmrg	r = rbits << (8 - pScrn->weight.red);
12327821949aSmrg	g = gbits << (8 - pScrn->weight.green);
12337821949aSmrg	b = bbits << (8 - pScrn->weight.blue);
12347821949aSmrg    }
12357821949aSmrg    else
12367821949aSmrg    {
12377821949aSmrg	uint32_t	bits;
12387821949aSmrg
12397821949aSmrg	bits = colorKey & ((1 << info->CurrentLayout.depth) - 1);
12407821949aSmrg	r = bits;
12417821949aSmrg	g = bits;
12427821949aSmrg	b = bits;
12437821949aSmrg    }
12447821949aSmrg    min = (r << 16) | (g << 8) | (b);
12457821949aSmrg    max = (0xff << 24) | (r << 16) | (g << 8) | (b);
12467821949aSmrg
12477821949aSmrg    RADEONWaitForFifo(pScrn, 2);
12487821949aSmrg    OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max);
12497821949aSmrg    OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min);
12507821949aSmrg}
1251de2362d3Smrg
1252de2362d3Smrgvoid
12537821949aSmrgRADEONResetVideo(ScrnInfoPtr pScrn)
12547821949aSmrg{
12557821949aSmrg    RADEONInfoPtr   info      = RADEONPTR(pScrn);
12567821949aSmrg    unsigned char *RADEONMMIO = info->MMIO;
12577821949aSmrg    RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
12587821949aSmrg    char tmp[200];
12597821949aSmrg
12607821949aSmrg    /* this function is called from ScreenInit. pScreen is used
12617821949aSmrg       by XAA internally, but not valid until ScreenInit finishs.
12627821949aSmrg    */
12637821949aSmrg    if (info->accelOn && pScrn->pScreen)
12647821949aSmrg	RADEON_SYNC(info, pScrn);
12657821949aSmrg
12667821949aSmrg    /* this is done here because each time the server is reset these
12677821949aSmrg       could change.. Otherwise they remain constant */
12687821949aSmrg    xvInstanceID = MAKE_ATOM("XV_INSTANCE_ID");
12697821949aSmrg    xvDeviceID = MAKE_ATOM("XV_DEVICE_ID");
12707821949aSmrg    xvLocationID = MAKE_ATOM("XV_LOCATION_ID");
12717821949aSmrg    xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS");
12727821949aSmrg
12737821949aSmrg    xvBrightness   = MAKE_ATOM("XV_BRIGHTNESS");
12747821949aSmrg    xvSaturation   = MAKE_ATOM("XV_SATURATION");
12757821949aSmrg    xvColor        = MAKE_ATOM("XV_COLOR");
12767821949aSmrg    xvContrast     = MAKE_ATOM("XV_CONTRAST");
12777821949aSmrg    xvColorKey     = MAKE_ATOM("XV_COLORKEY");
12787821949aSmrg    xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
12797821949aSmrg    xvHue          = MAKE_ATOM("XV_HUE");
12807821949aSmrg    xvRedIntensity   = MAKE_ATOM("XV_RED_INTENSITY");
12817821949aSmrg    xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY");
12827821949aSmrg    xvBlueIntensity  = MAKE_ATOM("XV_BLUE_INTENSITY");
12837821949aSmrg    xvGamma          = MAKE_ATOM("XV_GAMMA");
12847821949aSmrg    xvColorspace     = MAKE_ATOM("XV_COLORSPACE");
12857821949aSmrg
12867821949aSmrg    xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
12877821949aSmrg    xvSetDefaults       = MAKE_ATOM("XV_SET_DEFAULTS");
12887821949aSmrg    xvCRTC              = MAKE_ATOM("XV_CRTC");
12897821949aSmrg
12907821949aSmrg    xvOvAlpha	      = MAKE_ATOM("XV_OVERLAY_ALPHA");
12917821949aSmrg    xvGrAlpha	      = MAKE_ATOM("XV_GRAPHICS_ALPHA");
12927821949aSmrg    xvAlphaMode       = MAKE_ATOM("XV_ALPHA_MODE");
12937821949aSmrg
12947821949aSmrg    xvOverlayDeinterlacingMethod = MAKE_ATOM("XV_OVERLAY_DEINTERLACING_METHOD");
12957821949aSmrg
12967821949aSmrg    xvDecBrightness   = MAKE_ATOM("XV_DEC_BRIGHTNESS");
12977821949aSmrg    xvDecSaturation   = MAKE_ATOM("XV_DEC_SATURATION");
12987821949aSmrg    xvDecColor        = MAKE_ATOM("XV_DEC_COLOR");
12997821949aSmrg    xvDecContrast     = MAKE_ATOM("XV_DEC_CONTRAST");
13007821949aSmrg    xvDecHue          = MAKE_ATOM("XV_DEC_HUE");
13017821949aSmrg
13027821949aSmrg    xvEncoding        = MAKE_ATOM("XV_ENCODING");
13037821949aSmrg    xvFrequency       = MAKE_ATOM("XV_FREQ");
13047821949aSmrg    xvTunerStatus     = MAKE_ATOM("XV_TUNER_STATUS");
13057821949aSmrg    xvVolume          = MAKE_ATOM("XV_VOLUME");
13067821949aSmrg    xvMute            = MAKE_ATOM("XV_MUTE");
13077821949aSmrg    xvSAP             = MAKE_ATOM("XV_SAP");
13087821949aSmrg
13097821949aSmrg    xvAdjustment      = MAKE_ATOM("XV_DEBUG_ADJUSTMENT");
13107821949aSmrg
13117821949aSmrg    sprintf(tmp, "RXXX:%d.%d.%d", PCI_DEV_VENDOR_ID(info->PciInfo),
13127821949aSmrg	    PCI_DEV_DEVICE_ID(info->PciInfo), PCI_DEV_REVISION(info->PciInfo));
13137821949aSmrg    pPriv->device_id = MAKE_ATOM(tmp);
13147821949aSmrg    sprintf(tmp, "PCI:%02d:%02d.%d", PCI_DEV_BUS(info->PciInfo),
13157821949aSmrg	    PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo));
13167821949aSmrg    pPriv->location_id = MAKE_ATOM(tmp);
13177821949aSmrg    sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex);
13187821949aSmrg    pPriv->instance_id = MAKE_ATOM(tmp);
13197821949aSmrg
13207821949aSmrg    OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOFT_RESET);
13217821949aSmrg    OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0);   /* maybe */
13227821949aSmrg    OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0);
13237821949aSmrg    OUTREG(RADEON_OV0_FILTER_CNTL, RADEON_FILTER_PROGRAMMABLE_COEF);
13247821949aSmrg    OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ |
13257821949aSmrg				RADEON_VIDEO_KEY_FN_FALSE |
13267821949aSmrg				RADEON_CMP_MIX_OR);
13277821949aSmrg    OUTREG(RADEON_OV0_TEST, 0);
13287821949aSmrg    OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
13297821949aSmrg    OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
13307821949aSmrg    RADEONSetColorKey(pScrn, pPriv->colorKey);
13317821949aSmrg
13327821949aSmrg    if (info->ChipFamily == CHIP_FAMILY_RADEON) {
13337821949aSmrg
13347821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000);
13357821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e);
13367821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0);
13377821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442);
13387821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040);
13397821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
13407821949aSmrg
13417821949aSmrg    } else {
13427821949aSmrg
13437821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000);
13447821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e);
13457821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da);
13467821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442);
13477821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046);
13487821949aSmrg	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
13497821949aSmrg    }
13507821949aSmrg	/*
13517821949aSmrg	 * Set default Gamma ramp:
13527821949aSmrg	 *
13537821949aSmrg	 * Of 18 segments for gamma curve, all segments in R200 (and
13547821949aSmrg	 * newer) are programmable, while only lower 4 and upper 2
13557821949aSmrg	 * segments are programmable in the older Radeons.
13567821949aSmrg	 */
13577821949aSmrg
13587821949aSmrg    RADEONSetOverlayGamma(pScrn, 0); /* gamma = 1.0 */
13597821949aSmrg
13607821949aSmrg    if(pPriv->VIP!=NULL){
13617821949aSmrg        RADEONVIP_reset(pScrn,pPriv);
13627821949aSmrg        }
13637821949aSmrg
13647821949aSmrg    if(pPriv->theatre != NULL) {
13657821949aSmrg        xf86_InitTheatre(pPriv->theatre);
13667821949aSmrg/*      xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); */
13677821949aSmrg        }
13687821949aSmrg
13697821949aSmrg    if(pPriv->i2c != NULL){
13707821949aSmrg        RADEONResetI2C(pScrn, pPriv);
13717821949aSmrg        }
13727821949aSmrg}
13737821949aSmrg
13747821949aSmrgstatic void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
13757821949aSmrg{
13767821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
13777821949aSmrg    RADEONPLLPtr  pll = &(info->pll);
13787821949aSmrg    TheatrePtr t;
13797821949aSmrg
13807821949aSmrg    uint8_t a;
13817821949aSmrg    int i;
13827821949aSmrg
13837821949aSmrg    pPriv->theatre = NULL;
13847821949aSmrg
13857821949aSmrg    if(!info->MM_TABLE_valid &&
13867821949aSmrg       !((info->RageTheatreCrystal>=0) &&
13877821949aSmrg           (info->RageTheatreTunerPort>=0) && (info->RageTheatreCompositePort>=0) &&
13887821949aSmrg           (info->RageTheatreSVideoPort>=0)))
13897821949aSmrg    {
13907821949aSmrg       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no multimedia table present, disabling Rage Theatre.\n");
13917821949aSmrg       return;
13927821949aSmrg    }
13937821949aSmrg
13947821949aSmrg    /* Go and find Rage Theatre, if it exists */
13957821949aSmrg
13967821949aSmrg    if (info->IsMobility)
13977821949aSmrg	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n");
13987821949aSmrg    else
13997821949aSmrg	pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
14007821949aSmrg
14017821949aSmrg    if(pPriv->theatre==NULL)return;
14027821949aSmrg
14037821949aSmrg    /* just a matter of convenience */
14047821949aSmrg    t=pPriv->theatre;
14057821949aSmrg
14067821949aSmrg    t->video_decoder_type=info->video_decoder_type;
14077821949aSmrg
14087821949aSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type is 0x%04x (BIOS value) versus 0x%04x (current PLL setting)\n",
14097821949aSmrg         t->video_decoder_type, pll->xclk);
14107821949aSmrg
14117821949aSmrg    if(info->MM_TABLE_valid){
14127821949aSmrg         for(i=0;i<5;i++){
14137821949aSmrg                a=info->MM_TABLE.input[i];
14147821949aSmrg
14157821949aSmrg                switch(a & 0x3){
14167821949aSmrg                        case 1:
14177821949aSmrg                                t->wTunerConnector=i;
14187821949aSmrg                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tuner is on port %d\n",i);
14197821949aSmrg                                break;
14207821949aSmrg                        case 2:  if(a & 0x4){
14217821949aSmrg                                   t->wComp0Connector=RT_COMP2;
14227821949aSmrg                                   } else {
14237821949aSmrg                                   t->wComp0Connector=RT_COMP1;
14247821949aSmrg                                   }
14257821949aSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector);
14267821949aSmrg                                  break;
14277821949aSmrg                        case 3:  if(a & 0x4){
14287821949aSmrg                                   t->wSVideo0Connector=RT_YCR_COMP4;
14297821949aSmrg                                   } else {
14307821949aSmrg                                   t->wSVideo0Connector=RT_YCF_COMP4;
14317821949aSmrg                                   }
14327821949aSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector);
14337821949aSmrg                                   break;
14347821949aSmrg                        default:
14357821949aSmrg                                break;
14367821949aSmrg                        }
14377821949aSmrg                }
14387821949aSmrg        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n",
14397821949aSmrg    	     (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
14407821949aSmrg
14417821949aSmrg         }
14427821949aSmrg
14437821949aSmrg    if(info->RageTheatreTunerPort>=0)t->wTunerConnector=info->RageTheatreTunerPort;
14447821949aSmrg    if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort;
14457821949aSmrg    if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort;
14467821949aSmrg
14477821949aSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n",
14487821949aSmrg    	(unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
14497821949aSmrg
14507821949aSmrg    switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){
14517821949aSmrg                case 2700:
14527821949aSmrg                        t->video_decoder_type=RT_FREF_2700;
14537821949aSmrg                        break;
14547821949aSmrg                case 2950:
14557821949aSmrg                        t->video_decoder_type=RT_FREF_2950;
14567821949aSmrg                        break;
14577821949aSmrg                default:
14587821949aSmrg                        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
14597821949aSmrg                                "Unsupported reference clock frequency, Rage Theatre disabled\n");
14607821949aSmrg                        t->theatre_num=-1;
14617821949aSmrg			free(pPriv->theatre);
14627821949aSmrg			pPriv->theatre = NULL;
14637821949aSmrg			return;
14647821949aSmrg                }
14657821949aSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type used: 0x%04x\n", t->video_decoder_type);
14667821949aSmrg}
14677821949aSmrg
14687821949aSmrgstatic XF86VideoAdaptorPtr
14697821949aSmrgRADEONAllocAdaptor(ScrnInfoPtr pScrn)
14707821949aSmrg{
14717821949aSmrg    XF86VideoAdaptorPtr adapt;
14727821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
14737821949aSmrg    RADEONPortPrivPtr pPriv;
14747821949aSmrg    uint32_t dot_clock;
14757821949aSmrg    int ecp;
14767821949aSmrg
14777821949aSmrg    if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
14787821949aSmrg	return NULL;
14797821949aSmrg
14807821949aSmrg    if(!(pPriv = calloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion))))
14817821949aSmrg    {
14827821949aSmrg	free(adapt);
14837821949aSmrg	return NULL;
14847821949aSmrg    }
14857821949aSmrg
14867821949aSmrg    adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
14877821949aSmrg    adapt->pPortPrivates[0].ptr = (pointer)pPriv;
14887821949aSmrg
14897821949aSmrg    pPriv->colorKey = info->videoKey;
14907821949aSmrg    pPriv->doubleBuffer = TRUE;
14917821949aSmrg    pPriv->videoStatus = 0;
14927821949aSmrg    pPriv->brightness = 0;
14937821949aSmrg    pPriv->transform_index = 0;
14947821949aSmrg    pPriv->saturation = 0;
14957821949aSmrg    pPriv->contrast = 0;
14967821949aSmrg    pPriv->red_intensity = 0;
14977821949aSmrg    pPriv->green_intensity = 0;
14987821949aSmrg    pPriv->blue_intensity = 0;
14997821949aSmrg    pPriv->hue = 0;
15007821949aSmrg    pPriv->currentBuffer = 0;
15017821949aSmrg    pPriv->autopaint_colorkey = TRUE;
15027821949aSmrg    pPriv->gamma = 1000;
15037821949aSmrg    pPriv->desired_crtc = NULL;
15047821949aSmrg
15057821949aSmrg    pPriv->ov_alpha = 255;
15067821949aSmrg    pPriv->gr_alpha = 255;
15077821949aSmrg    pPriv->alpha_mode = 0;
15087821949aSmrg
15097821949aSmrg       /* TV-in stuff */
15107821949aSmrg    pPriv->video_stream_active = FALSE;
15117821949aSmrg    pPriv->encoding = 4;
15127821949aSmrg    pPriv->frequency = 1000;
15137821949aSmrg    pPriv->volume = -1000;
15147821949aSmrg    pPriv->mute = TRUE;
15157821949aSmrg    pPriv->v = 0;
15167821949aSmrg    pPriv->overlay_deinterlacing_method = METHOD_BOB;
15177821949aSmrg    pPriv->capture_vbi_data = 0;
15187821949aSmrg    pPriv->dec_brightness = 0;
15197821949aSmrg    pPriv->dec_saturation = 0;
15207821949aSmrg    pPriv->dec_contrast = 0;
15217821949aSmrg    pPriv->dec_hue = 0;
15227821949aSmrg
15237821949aSmrg
15247821949aSmrg    /*
15257821949aSmrg     * Unlike older Mach64 chips, RADEON has only two ECP settings:
15267821949aSmrg     * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
15277821949aSmrg     * for higher clocks, sure makes life nicer
15287821949aSmrg     */
15297821949aSmrg    dot_clock = info->ModeReg->dot_clock_freq;
15307821949aSmrg
15317821949aSmrg    if (dot_clock < 17500)
15327821949aSmrg        info->ecp_div = 0;
15337821949aSmrg    else
15347821949aSmrg        info->ecp_div = 1;
15357821949aSmrg    ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
15367821949aSmrg
15377821949aSmrg    if (info->IsIGP) {
15387821949aSmrg        /* Force the overlay clock on for integrated chips
15397821949aSmrg	 */
15407821949aSmrg        ecp |= (1<<18);
15417821949aSmrg    }
15427821949aSmrg
15437821949aSmrg    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp);
15447821949aSmrg
15457821949aSmrg
15467821949aSmrg    /* Decide on tuner type */
15477821949aSmrg    if((info->tunerType<0) && (info->MM_TABLE_valid)) {
15487821949aSmrg        pPriv->tuner_type = info->MM_TABLE.tuner_type;
15497821949aSmrg    	} else
15507821949aSmrg        pPriv->tuner_type = info->tunerType;
15517821949aSmrg
15527821949aSmrg    /* Initialize I2C bus */
15537821949aSmrg    RADEONInitI2C(pScrn, pPriv);
15547821949aSmrg    if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
15557821949aSmrg
15567821949aSmrg
15577821949aSmrg    #if 0  /* this is just here for easy debugging - normally off */
15587821949aSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n");
15597821949aSmrg    for(i=0;i<255;i+=2)
15607821949aSmrg        if(RADEONProbeAddress(pPriv->i2c, i))
15617821949aSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "     found device at address 0x%02x\n", i);
15627821949aSmrg    #endif
15637821949aSmrg
15647821949aSmrg    /* resetting the VIP bus causes problems with some mobility chips.
15657821949aSmrg     * we don't support video in on any mobility chips at the moment anyway
15667821949aSmrg     */
15677821949aSmrg    /* Initialize VIP bus */
15687821949aSmrg    if (!info->IsMobility)
15697821949aSmrg	RADEONVIP_init(pScrn, pPriv);
15707821949aSmrg
15717821949aSmrg    info->adaptor = adapt;
15727821949aSmrg    info->xv_max_width = 2047;
15737821949aSmrg    info->xv_max_height = 2047;
15747821949aSmrg
15757821949aSmrg	if(!xf86LoadSubModule(pScrn,"theatre_detect"))
15767821949aSmrg	{
15777821949aSmrg		xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n");
15787821949aSmrg		goto skip_theatre;
15797821949aSmrg    }
15807821949aSmrg	RADEONSetupTheatre(pScrn, pPriv);
15817821949aSmrg
15827821949aSmrg	/*
15837821949aSmrg	 * Now load the correspondind theatre chip based on what has been detected.
15847821949aSmrg	 */
15857821949aSmrg	if (pPriv->theatre)
15867821949aSmrg	{
15877821949aSmrg		xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Going to load the corresponding theatre module\n");
15887821949aSmrg		switch (pPriv->theatre->theatre_id)
15897821949aSmrg		{
15907821949aSmrg			case RT100_ATI_ID:
15917821949aSmrg			{
15927821949aSmrg				if(!xf86LoadSubModule(pScrn,"theatre"))
15937821949aSmrg				{
15947821949aSmrg					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
15957821949aSmrg					free(pPriv->theatre);
15967821949aSmrg					goto skip_theatre;
15977821949aSmrg				}
15987821949aSmrg				break;
15997821949aSmrg			}
16007821949aSmrg			case RT200_ATI_ID:
16017821949aSmrg			{
16027821949aSmrg				if(!xf86LoadSubModule(pScrn,"theatre200"))
16037821949aSmrg				{
16047821949aSmrg					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
16057821949aSmrg					free(pPriv->theatre);
16067821949aSmrg					goto skip_theatre;
16077821949aSmrg				}
16087821949aSmrg				pPriv->theatre->microc_path = info->RageTheatreMicrocPath;
16097821949aSmrg				pPriv->theatre->microc_type = info->RageTheatreMicrocType;
16107821949aSmrg				break;
16117821949aSmrg			}
16127821949aSmrg			default:
16137821949aSmrg			{
16147821949aSmrg				xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unknown Theatre chip\n");
16157821949aSmrg				free(pPriv->theatre);
16167821949aSmrg				goto skip_theatre;
16177821949aSmrg			}
16187821949aSmrg		}
1619de2362d3Smrg	}
16207821949aSmrg
16217821949aSmrg	if(pPriv->theatre!=NULL)
16227821949aSmrg	{
16237821949aSmrg		xf86_InitTheatre(pPriv->theatre);
16247821949aSmrg		if(pPriv->theatre->mode == MODE_UNINITIALIZED)
16257821949aSmrg		{
16267821949aSmrg			free(pPriv->theatre);
16277821949aSmrg			pPriv->theatre = NULL;
16287821949aSmrg			xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Rage Theatre disabled\n");
16297821949aSmrg			/* Here the modules must be unloaded */
16307821949aSmrg			goto skip_theatre;
16317821949aSmrg		}
1632de2362d3Smrg	}
16337821949aSmrg
16347821949aSmrg    if(pPriv->theatre!=NULL){
16357821949aSmrg        xf86_ResetTheatreRegsForNoTVout(pPriv->theatre);
16367821949aSmrg        xf86_RT_SetTint(pPriv->theatre, pPriv->dec_hue);
16377821949aSmrg        xf86_RT_SetSaturation(pPriv->theatre, pPriv->dec_saturation);
16387821949aSmrg        xf86_RT_SetSharpness(pPriv->theatre, RT_NORM_SHARPNESS);
16397821949aSmrg        xf86_RT_SetContrast(pPriv->theatre, pPriv->dec_contrast);
16407821949aSmrg        xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
1641de2362d3Smrg
16427821949aSmrg        RADEON_RT_SetEncoding(pScrn, pPriv);
16437821949aSmrg	}
16447821949aSmrg
16457821949aSmrgskip_theatre:
16467821949aSmrg
16477821949aSmrg    return adapt;
16487821949aSmrg}
16497821949aSmrg
16507821949aSmrgstatic XF86VideoAdaptorPtr
16517821949aSmrgRADEONSetupImageVideo(ScreenPtr pScreen)
16527821949aSmrg{
16537821949aSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
16547821949aSmrg    RADEONPortPrivPtr pPriv;
16557821949aSmrg    XF86VideoAdaptorPtr adapt;
16567821949aSmrg
16577821949aSmrg    if(!(adapt = RADEONAllocAdaptor(pScrn)))
16587821949aSmrg	return NULL;
16597821949aSmrg
16607821949aSmrg    adapt->type = XvWindowMask | XvInputMask | XvImageMask;
16617821949aSmrg    adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
16627821949aSmrg    adapt->name = "ATI Radeon Video Overlay";
16637821949aSmrg    adapt->nEncodings = 1;
16647821949aSmrg    adapt->pEncodings = &DummyEncoding;
16657821949aSmrg    adapt->nFormats = NUM_FORMATS;
16667821949aSmrg    adapt->pFormats = Formats;
16677821949aSmrg    adapt->nPorts = 1;
16687821949aSmrg    adapt->nAttributes = NUM_ATTRIBUTES;
16697821949aSmrg    adapt->pAttributes = Attributes;
16707821949aSmrg    adapt->nImages = NUM_IMAGES;
16717821949aSmrg    adapt->pImages = Images;
16727821949aSmrg    adapt->PutVideo = NULL;
16737821949aSmrg    adapt->PutStill = NULL;
16747821949aSmrg    adapt->GetVideo = NULL;
16757821949aSmrg    adapt->GetStill = NULL;
16767821949aSmrg    adapt->StopVideo = RADEONStopVideo;
16777821949aSmrg    adapt->SetPortAttribute = RADEONSetPortAttribute;
16787821949aSmrg    adapt->GetPortAttribute = RADEONGetPortAttribute;
16797821949aSmrg    adapt->QueryBestSize = RADEONQueryBestSize;
16807821949aSmrg    adapt->PutImage = RADEONPutImage;
16817821949aSmrg    adapt->QueryImageAttributes = RADEONQueryImageAttributes;
16827821949aSmrg
16837821949aSmrg    pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr);
16847821949aSmrg    REGION_NULL(pScreen, &(pPriv->clip));
16857821949aSmrg
16867821949aSmrg    pPriv->textured = FALSE;
16877821949aSmrg
16887821949aSmrg    if(pPriv->theatre != NULL) {
16897821949aSmrg	/* video decoder is present, extend capabilities */
16907821949aSmrg       adapt->nEncodings = 13;
16917821949aSmrg       adapt->pEncodings = InputVideoEncodings;
16927821949aSmrg       adapt->type |= XvVideoMask;
16937821949aSmrg       adapt->nAttributes = NUM_DEC_ATTRIBUTES;
16947821949aSmrg       adapt->PutVideo = RADEONPutVideo;
16957821949aSmrg    }
16967821949aSmrg
16977821949aSmrg    RADEONResetVideo(pScrn);
16987821949aSmrg
16997821949aSmrg    return adapt;
17007821949aSmrg}
17017821949aSmrg
17027821949aSmrgvoid
17037821949aSmrgRADEONFreeVideoMemory(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
17047821949aSmrg{
17057821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
17067821949aSmrg
17077821949aSmrg    if (pPriv->video_memory != NULL) {
17087821949aSmrg	radeon_legacy_free_memory(pScrn, pPriv->video_memory);
17097821949aSmrg	pPriv->video_memory = NULL;
17107821949aSmrg
17117821949aSmrg	if (info->cs && pPriv->textured) {
17127821949aSmrg	    pPriv->src_bo[0] = NULL;
17137821949aSmrg	    radeon_legacy_free_memory(pScrn, pPriv->src_bo[1]);
17147821949aSmrg	    pPriv->src_bo[1] = NULL;
17157821949aSmrg	}
17167821949aSmrg    }
17177821949aSmrg}
17187821949aSmrg
17197821949aSmrgvoid
17207821949aSmrgRADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
17217821949aSmrg{
17227821949aSmrg  RADEONInfoPtr info = RADEONPTR(pScrn);
17237821949aSmrg  unsigned char *RADEONMMIO = info->MMIO;
17247821949aSmrg  RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
17257821949aSmrg
17267821949aSmrg  if (pPriv->textured) {
17277821949aSmrg      if (cleanup) {
17287821949aSmrg	  RADEONFreeVideoMemory(pScrn, pPriv);
17297821949aSmrg      }
17307821949aSmrg      return;
17317821949aSmrg  }
17327821949aSmrg
17337821949aSmrg  REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
17347821949aSmrg
17357821949aSmrg  if(cleanup) {
17367821949aSmrg     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
17377821949aSmrg	RADEONWaitForFifo(pScrn, 2);
17387821949aSmrg	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
17397821949aSmrg     }
17407821949aSmrg     if(pPriv->video_stream_active){
17417821949aSmrg        RADEONWaitForFifo(pScrn, 2);
17427821949aSmrg        OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
17437821949aSmrg        OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
17447821949aSmrg        RADEONResetVideo(pScrn);
17457821949aSmrg        pPriv->video_stream_active = FALSE;
17467821949aSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
17477821949aSmrg		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE);
17487821949aSmrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
17497821949aSmrg     }
17507821949aSmrg     RADEONFreeVideoMemory(pScrn, pPriv);
17517821949aSmrg     pPriv->videoStatus = 0;
17527821949aSmrg  } else {
17537821949aSmrg     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
17547821949aSmrg	pPriv->videoStatus |= OFF_TIMER;
17557821949aSmrg	pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
17567821949aSmrg     }
17577821949aSmrg  }
17587821949aSmrg}
17597821949aSmrg
17607821949aSmrgint
17617821949aSmrgRADEONSetPortAttribute(ScrnInfoPtr  pScrn,
17627821949aSmrg		       Atom	    attribute,
17637821949aSmrg		       INT32	    value,
17647821949aSmrg		       pointer	    data)
17657821949aSmrg{
17667821949aSmrg    RADEONInfoPtr	info = RADEONPTR(pScrn);
17677821949aSmrg    RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
17687821949aSmrg    Bool		setTransform = FALSE;
17697821949aSmrg    Bool		setAlpha = FALSE;
17707821949aSmrg    unsigned char *RADEONMMIO = info->MMIO;
17717821949aSmrg
17727821949aSmrg    RADEON_SYNC(info, pScrn);
17737821949aSmrg
17747821949aSmrg    if(attribute == xvAutopaintColorkey)
17757821949aSmrg    {
17767821949aSmrg	pPriv->autopaint_colorkey = ClipValue (value, 0, 1);
17777821949aSmrg    }
17787821949aSmrg    else if(attribute == xvSetDefaults)
17797821949aSmrg    {
17807821949aSmrg	pPriv->autopaint_colorkey = TRUE;
17817821949aSmrg	pPriv->brightness = 0;
17827821949aSmrg	pPriv->saturation = 0;
17837821949aSmrg	pPriv->contrast = 0;
17847821949aSmrg	pPriv->hue = 0;
17857821949aSmrg	pPriv->red_intensity = 0;
17867821949aSmrg	pPriv->green_intensity = 0;
17877821949aSmrg	pPriv->blue_intensity = 0;
17887821949aSmrg	pPriv->gamma = 1000;
17897821949aSmrg	pPriv->transform_index = 0;
17907821949aSmrg	pPriv->doubleBuffer = FALSE;
17917821949aSmrg	pPriv->ov_alpha = 255;
17927821949aSmrg	pPriv->gr_alpha = 255;
17937821949aSmrg	pPriv->alpha_mode = 0;
17947821949aSmrg
17957821949aSmrg        /* It is simpler to call itself */
17967821949aSmrg        RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data);
17977821949aSmrg        RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data);
17987821949aSmrg        RADEONSetPortAttribute(pScrn, xvDecContrast,   0, data);
17997821949aSmrg        RADEONSetPortAttribute(pScrn, xvDecHue,   0, data);
18007821949aSmrg
18017821949aSmrg        RADEONSetPortAttribute(pScrn, xvVolume,   -1000, data);
18027821949aSmrg        RADEONSetPortAttribute(pScrn, xvMute,   1, data);
18037821949aSmrg        RADEONSetPortAttribute(pScrn, xvSAP,   0, data);
18047821949aSmrg        RADEONSetPortAttribute(pScrn, xvDoubleBuffer,   1, data);
18057821949aSmrg
18067821949aSmrg	setTransform = TRUE;
18077821949aSmrg	setAlpha = TRUE;
18087821949aSmrg    }
18097821949aSmrg    else if(attribute == xvBrightness)
18107821949aSmrg    {
18117821949aSmrg	pPriv->brightness = ClipValue (value, -1000, 1000);
18127821949aSmrg	setTransform = TRUE;
18137821949aSmrg    }
18147821949aSmrg    else if((attribute == xvSaturation) || (attribute == xvColor))
18157821949aSmrg    {
18167821949aSmrg	pPriv->saturation = ClipValue (value, -1000, 1000);
18177821949aSmrg	setTransform = TRUE;
18187821949aSmrg    }
18197821949aSmrg    else if(attribute == xvContrast)
18207821949aSmrg    {
18217821949aSmrg	pPriv->contrast = ClipValue (value, -1000, 1000);
18227821949aSmrg	setTransform = TRUE;
18237821949aSmrg    }
18247821949aSmrg    else if(attribute == xvHue)
18257821949aSmrg    {
18267821949aSmrg	pPriv->hue = ClipValue (value, -1000, 1000);
18277821949aSmrg	setTransform = TRUE;
18287821949aSmrg    }
18297821949aSmrg    else if(attribute == xvRedIntensity)
18307821949aSmrg    {
18317821949aSmrg	pPriv->red_intensity = ClipValue (value, -1000, 1000);
18327821949aSmrg	setTransform = TRUE;
18337821949aSmrg    }
18347821949aSmrg    else if(attribute == xvGreenIntensity)
18357821949aSmrg    {
18367821949aSmrg	pPriv->green_intensity = ClipValue (value, -1000, 1000);
18377821949aSmrg	setTransform = TRUE;
18387821949aSmrg    }
18397821949aSmrg    else if(attribute == xvBlueIntensity)
18407821949aSmrg    {
18417821949aSmrg	pPriv->blue_intensity = ClipValue (value, -1000, 1000);
18427821949aSmrg	setTransform = TRUE;
18437821949aSmrg    }
18447821949aSmrg    else if(attribute == xvGamma)
18457821949aSmrg    {
18467821949aSmrg	pPriv->gamma = ClipValue (value, 100, 10000);
18477821949aSmrg	setTransform = TRUE;
18487821949aSmrg    }
18497821949aSmrg    else if(attribute == xvColorspace)
18507821949aSmrg    {
18517821949aSmrg	pPriv->transform_index = ClipValue (value, 0, 1);
18527821949aSmrg	setTransform = TRUE;
18537821949aSmrg    }
18547821949aSmrg    else if(attribute == xvDoubleBuffer)
18557821949aSmrg    {
18567821949aSmrg	pPriv->doubleBuffer = ClipValue (value, 0, 1);
18577821949aSmrg    }
18587821949aSmrg    else if(attribute == xvColorKey)
18597821949aSmrg    {
18607821949aSmrg	pPriv->colorKey = value;
18617821949aSmrg	RADEONSetColorKey (pScrn, pPriv->colorKey);
18627821949aSmrg	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
18637821949aSmrg    }
18647821949aSmrg    else if(attribute == xvCRTC)
18657821949aSmrg    {
18667821949aSmrg	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
18677821949aSmrg	if ((value < -1) || (value > xf86_config->num_crtc))
18687821949aSmrg	    return BadValue;
18697821949aSmrg	if (value < 0)
18707821949aSmrg	    pPriv->desired_crtc = NULL;
18717821949aSmrg	else
18727821949aSmrg	    pPriv->desired_crtc = xf86_config->crtc[value];
18737821949aSmrg    }
18747821949aSmrg    else if(attribute == xvOvAlpha)
18757821949aSmrg    {
18767821949aSmrg	pPriv->ov_alpha = ClipValue (value, 0, 255);
18777821949aSmrg	setAlpha = TRUE;
18787821949aSmrg    }
18797821949aSmrg    else if(attribute == xvGrAlpha)
18807821949aSmrg    {
18817821949aSmrg	pPriv->gr_alpha = ClipValue (value, 0, 255);
18827821949aSmrg	setAlpha = TRUE;
18837821949aSmrg    }
18847821949aSmrg    else if(attribute == xvAlphaMode)
18857821949aSmrg    {
18867821949aSmrg	pPriv->alpha_mode = ClipValue (value, 0, 1);
18877821949aSmrg	setAlpha = TRUE;
18887821949aSmrg    }
18897821949aSmrg    else if(attribute == xvDecBrightness)
18907821949aSmrg    {
18917821949aSmrg        pPriv->dec_brightness = value;
18927821949aSmrg        if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
18937821949aSmrg    }
18947821949aSmrg    else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
18957821949aSmrg    {
18967821949aSmrg        if(value<-1000)value = -1000;
18977821949aSmrg        if(value>1000)value = 1000;
18987821949aSmrg        pPriv->dec_saturation = value;
18997821949aSmrg        if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value);
19007821949aSmrg    }
19017821949aSmrg    else if(attribute == xvDecContrast)
19027821949aSmrg    {
19037821949aSmrg        pPriv->dec_contrast = value;
19047821949aSmrg        if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value);
19057821949aSmrg    }
19067821949aSmrg    else if(attribute == xvDecHue)
19077821949aSmrg    {
19087821949aSmrg        pPriv->dec_hue = value;
19097821949aSmrg        if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value);
19107821949aSmrg    }
19117821949aSmrg    else if(attribute == xvEncoding)
19127821949aSmrg    {
19137821949aSmrg        pPriv->encoding = value;
19147821949aSmrg        if(pPriv->video_stream_active)
19157821949aSmrg        {
19167821949aSmrg           if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);
19177821949aSmrg           if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
19187821949aSmrg           if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
19197821949aSmrg	   if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
19207821949aSmrg           if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
19217821949aSmrg        /* put more here to actually change it */
19227821949aSmrg        }
19237821949aSmrg   }
19247821949aSmrg   else if(attribute == xvFrequency)
19257821949aSmrg   {
19267821949aSmrg        pPriv->frequency = value;
19277821949aSmrg        /* mute volume if it was not muted before */
19287821949aSmrg        if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
19297821949aSmrg		if((pPriv->uda1380!=NULL)&& !pPriv->mute)xf86_uda1380_mute(pPriv->uda1380, TRUE);
19307821949aSmrg        if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value);
19317821949aSmrg/*        if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);  */
19327821949aSmrg        if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck))
19337821949aSmrg                xf86_InitMSP3430(pPriv->msp3430);
19347821949aSmrg        if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume));
19357821949aSmrg		if((pPriv->uda1380 != NULL)&& !pPriv->mute) xf86_uda1380_setvolume(pPriv->uda1380, pPriv->volume);
19367821949aSmrg   }
19377821949aSmrg   else if(attribute == xvMute)
19387821949aSmrg   {
19397821949aSmrg        pPriv->mute = value;
19407821949aSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
19417821949aSmrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
19427821949aSmrg		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, pPriv->mute);
19437821949aSmrg   }
19447821949aSmrg   else if(attribute == xvSAP)
19457821949aSmrg   {
19467821949aSmrg        pPriv->sap_channel = value;
19477821949aSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3);
19487821949aSmrg   }
19497821949aSmrg   else if(attribute == xvVolume)
19507821949aSmrg   {
19517821949aSmrg        if(value<-1000)value = -1000;
19527821949aSmrg        if(value>1000)value = 1000;
19537821949aSmrg        pPriv->volume = value;
19547821949aSmrg        pPriv->mute = FALSE;
19557821949aSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value));
19567821949aSmrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
19577821949aSmrg		if(pPriv->uda1380 != NULL) xf86_uda1380_setvolume(pPriv->uda1380, value);
19587821949aSmrg   }
19597821949aSmrg   else if(attribute == xvOverlayDeinterlacingMethod)
19607821949aSmrg   {
19617821949aSmrg        if(value<0)value = 0;
19627821949aSmrg        if(value>2)value = 2;
19637821949aSmrg        pPriv->overlay_deinterlacing_method = value;
19647821949aSmrg        switch(pPriv->overlay_deinterlacing_method){
19657821949aSmrg                case METHOD_BOB:
19667821949aSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
19677821949aSmrg                        break;
19687821949aSmrg                case METHOD_SINGLE:
19697821949aSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
19707821949aSmrg                        break;
19717821949aSmrg                case METHOD_WEAVE:
19727821949aSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0);
19737821949aSmrg                        break;
19747821949aSmrg                default:
19757821949aSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
19767821949aSmrg                }
19777821949aSmrg   }
19787821949aSmrg   else if(attribute == xvDumpStatus)
19797821949aSmrg   {
19807821949aSmrg  	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n",
19817821949aSmrg		pScrn->currentMode->Flags,
19827821949aSmrg		pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" ,
19837821949aSmrg		pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : ""
19847821949aSmrg		);
19857821949aSmrg	if(pPriv->tda9885 != NULL){
19867821949aSmrg		xf86_tda9885_getstatus(pPriv->tda9885);
19877821949aSmrg		xf86_tda9885_dumpstatus(pPriv->tda9885);
19887821949aSmrg		}
19897821949aSmrg	if(pPriv->fi1236!=NULL){
19907821949aSmrg		xf86_fi1236_dump_status(pPriv->fi1236);
19917821949aSmrg		}
19927821949aSmrg   }
19937821949aSmrg   else if(attribute == xvAdjustment)
19947821949aSmrg   {
19957821949aSmrg  	pPriv->adjustment=value;
19967821949aSmrg        xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n",
19977821949aSmrg		   (unsigned)pPriv->adjustment);
19987821949aSmrg  	if(pPriv->tda9885!=0){
19997821949aSmrg		pPriv->tda9885->top_adjustment=value;
20007821949aSmrg		RADEON_TDA9885_SetEncoding(pPriv);
20017821949aSmrg		}
20027821949aSmrg   }
20037821949aSmrg   else
20047821949aSmrg	return BadMatch;
20057821949aSmrg
20067821949aSmrg    if (setTransform)
20077821949aSmrg    {
20087821949aSmrg	RADEONSetTransform(pScrn,
20097821949aSmrg			   RTFBrightness(pPriv->brightness),
20107821949aSmrg			   RTFContrast(pPriv->contrast),
20117821949aSmrg			   RTFSaturation(pPriv->saturation),
20127821949aSmrg			   RTFHue(pPriv->hue),
20137821949aSmrg			   RTFIntensity(pPriv->red_intensity),
20147821949aSmrg			   RTFIntensity(pPriv->green_intensity),
20157821949aSmrg			   RTFIntensity(pPriv->blue_intensity),
20167821949aSmrg			   pPriv->transform_index,
20177821949aSmrg			   pPriv->gamma);
20187821949aSmrg    }
20197821949aSmrg
20207821949aSmrg    if (setAlpha)
20217821949aSmrg    {
20227821949aSmrg	RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode);
20237821949aSmrg    }
20247821949aSmrg
20257821949aSmrg    return Success;
20267821949aSmrg}
20277821949aSmrg
20287821949aSmrgint
20297821949aSmrgRADEONGetPortAttribute(ScrnInfoPtr  pScrn,
20307821949aSmrg		       Atom	    attribute,
20317821949aSmrg		       INT32	    *value,
20327821949aSmrg		       pointer	    data)
20337821949aSmrg{
20347821949aSmrg    RADEONInfoPtr	info = RADEONPTR(pScrn);
20357821949aSmrg    RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
20367821949aSmrg
20377821949aSmrg    if (info->accelOn) RADEON_SYNC(info, pScrn);
20387821949aSmrg
20397821949aSmrg    if(attribute == xvAutopaintColorkey)
20407821949aSmrg	*value = pPriv->autopaint_colorkey;
20417821949aSmrg    else if(attribute == xvBrightness)
20427821949aSmrg	*value = pPriv->brightness;
20437821949aSmrg    else if((attribute == xvSaturation) || (attribute == xvColor))
20447821949aSmrg	*value = pPriv->saturation;
20457821949aSmrg    else if(attribute == xvContrast)
20467821949aSmrg	*value = pPriv->contrast;
20477821949aSmrg    else if(attribute == xvHue)
20487821949aSmrg	*value = pPriv->hue;
20497821949aSmrg    else if(attribute == xvRedIntensity)
20507821949aSmrg	*value = pPriv->red_intensity;
20517821949aSmrg    else if(attribute == xvGreenIntensity)
20527821949aSmrg	*value = pPriv->green_intensity;
20537821949aSmrg    else if(attribute == xvBlueIntensity)
20547821949aSmrg	*value = pPriv->blue_intensity;
20557821949aSmrg    else if(attribute == xvGamma)
20567821949aSmrg	*value = pPriv->gamma;
20577821949aSmrg    else if(attribute == xvColorspace)
20587821949aSmrg	*value = pPriv->transform_index;
20597821949aSmrg    else if(attribute == xvDoubleBuffer)
20607821949aSmrg	*value = pPriv->doubleBuffer ? 1 : 0;
20617821949aSmrg    else if(attribute == xvColorKey)
20627821949aSmrg	*value = pPriv->colorKey;
20637821949aSmrg    else if(attribute == xvCRTC) {
20647821949aSmrg	int		c;
20657821949aSmrg	xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
20667821949aSmrg	for (c = 0; c < xf86_config->num_crtc; c++)
20677821949aSmrg	    if (xf86_config->crtc[c] == pPriv->desired_crtc)
20687821949aSmrg		break;
20697821949aSmrg	if (c == xf86_config->num_crtc)
20707821949aSmrg	    c = -1;
20717821949aSmrg	*value = c;
20727821949aSmrg    }
20737821949aSmrg    else if(attribute == xvOvAlpha)
20747821949aSmrg	*value = pPriv->ov_alpha;
20757821949aSmrg    else if(attribute == xvGrAlpha)
20767821949aSmrg	*value = pPriv->gr_alpha;
20777821949aSmrg    else if(attribute == xvAlphaMode)
20787821949aSmrg	*value = pPriv->alpha_mode;
20797821949aSmrg    else if(attribute == xvDecBrightness)
20807821949aSmrg        *value = pPriv->dec_brightness;
20817821949aSmrg    else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
20827821949aSmrg        *value = pPriv->dec_saturation;
20837821949aSmrg    else if(attribute == xvDecContrast)
20847821949aSmrg        *value = pPriv->dec_contrast;
20857821949aSmrg    else if(attribute == xvDecHue)
20867821949aSmrg        *value = pPriv->dec_hue;
20877821949aSmrg    else if(attribute == xvEncoding)
20887821949aSmrg        *value = pPriv->encoding;
20897821949aSmrg    else if(attribute == xvFrequency)
20907821949aSmrg        *value = pPriv->frequency;
20917821949aSmrg    else
20927821949aSmrg    if(attribute == xvTunerStatus) {
20937821949aSmrg        if(pPriv->fi1236==NULL){
20947821949aSmrg                *value=TUNER_OFF;
20957821949aSmrg                } else
20967821949aSmrg                {
20977821949aSmrg                *value = xf86_TUNER_get_afc_hint(pPriv->fi1236);
20987821949aSmrg                }
20997821949aSmrg       }
21007821949aSmrg    else if(attribute == xvMute)
21017821949aSmrg        *value = pPriv->mute;
21027821949aSmrg    else if(attribute == xvSAP)
21037821949aSmrg        *value = pPriv->sap_channel;
21047821949aSmrg    else if(attribute == xvVolume)
21057821949aSmrg        *value = pPriv->volume;
21067821949aSmrg    else if(attribute == xvOverlayDeinterlacingMethod)
21077821949aSmrg        *value = pPriv->overlay_deinterlacing_method;
21087821949aSmrg    else if(attribute == xvDeviceID)
21097821949aSmrg        *value = pPriv->device_id;
21107821949aSmrg    else if(attribute == xvLocationID)
21117821949aSmrg        *value = pPriv->location_id;
21127821949aSmrg    else if(attribute == xvInstanceID)
21137821949aSmrg        *value = pPriv->instance_id;
21147821949aSmrg    else if(attribute == xvAdjustment)
21157821949aSmrg  	*value = pPriv->adjustment;
21167821949aSmrg    else
21177821949aSmrg	return BadMatch;
21187821949aSmrg
21197821949aSmrg    return Success;
21207821949aSmrg}
21217821949aSmrg
21227821949aSmrgvoid
21237821949aSmrgRADEONQueryBestSize(
21247821949aSmrg  ScrnInfoPtr pScrn,
21257821949aSmrg  Bool motion,
21267821949aSmrg  short vid_w, short vid_h,
21277821949aSmrg  short drw_w, short drw_h,
21287821949aSmrg  unsigned int *p_w, unsigned int *p_h,
21297821949aSmrg  pointer data
21307821949aSmrg){
21317821949aSmrg    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
21327821949aSmrg
21337821949aSmrg    if (!pPriv->textured) {
21347821949aSmrg	if (vid_w > (drw_w << 4))
21357821949aSmrg	    drw_w = vid_w >> 4;
21367821949aSmrg	if (vid_h > (drw_h << 4))
21377821949aSmrg	    drw_h = vid_h >> 4;
21387821949aSmrg    }
21397821949aSmrg
21407821949aSmrg  *p_w = drw_w;
21417821949aSmrg  *p_h = drw_h;
21427821949aSmrg}
21437821949aSmrg
21447821949aSmrgstatic struct {
21457821949aSmrg	double range;
21467821949aSmrg	signed char coeff[5][4];
21477821949aSmrg	} TapCoeffs[]=
21487821949aSmrg	{
21497821949aSmrg        {0.25, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13,   13,    3}, }},
21507821949aSmrg        {0.26, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21517821949aSmrg        {0.27, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21527821949aSmrg        {0.28, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21537821949aSmrg        {0.29, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21547821949aSmrg        {0.30, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21557821949aSmrg        {0.31, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21567821949aSmrg        {0.32, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21577821949aSmrg        {0.33, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21587821949aSmrg        {0.34, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21597821949aSmrg        {0.35, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21607821949aSmrg        {0.36, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21617821949aSmrg        {0.37, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21627821949aSmrg        {0.38, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21637821949aSmrg        {0.39, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21647821949aSmrg        {0.40, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21657821949aSmrg        {0.41, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21667821949aSmrg        {0.42, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21677821949aSmrg        {0.43, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21687821949aSmrg        {0.44, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21697821949aSmrg        {0.45, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21707821949aSmrg        {0.46, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21717821949aSmrg        {0.47, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21727821949aSmrg        {0.48, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21737821949aSmrg        {0.49, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21747821949aSmrg        {0.50, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
21757821949aSmrg        {0.51, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 2,   14, 14,  2}, }},
21767821949aSmrg        {0.52, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
21777821949aSmrg        {0.53, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
21787821949aSmrg        {0.54, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
21797821949aSmrg        {0.55, {{ 7,    18,  7,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 1,   15, 15,  1}, }},
21807821949aSmrg        {0.56, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21817821949aSmrg        {0.57, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21827821949aSmrg        {0.58, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21837821949aSmrg        {0.59, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21847821949aSmrg        {0.60, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21857821949aSmrg        {0.61, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21867821949aSmrg        {0.62, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21877821949aSmrg        {0.63, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21887821949aSmrg        {0.64, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
21897821949aSmrg        {0.65, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
21907821949aSmrg        {0.66, {{ 7,    18,  8, -1}, { 6,   18, 10, -2}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
21917821949aSmrg        {0.67, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   18, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
21927821949aSmrg        {0.68, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
21937821949aSmrg        {0.69, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
21947821949aSmrg        {0.70, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
21957821949aSmrg        {0.71, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
21967821949aSmrg        {0.72, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
21977821949aSmrg        {0.73, {{ 7,    20,  7, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
21987821949aSmrg        {0.74, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
21997821949aSmrg        {0.75, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
22007821949aSmrg        {0.76, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
22017821949aSmrg        {0.77, {{ 6,    22,  6, -2}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
22027821949aSmrg        {0.78, {{ 6,    21,  6, -1}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
22037821949aSmrg        {0.79, {{ 5,    23,  5, -1}, { 3,   22,  9, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
22047821949aSmrg        {0.80, {{ 5,    23,  5, -1}, { 3,   23,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
22057821949aSmrg        {0.81, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
22067821949aSmrg        {0.82, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-3,   19, 19, -3}, }},
22077821949aSmrg        {0.83, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
22087821949aSmrg        {0.84, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
22097821949aSmrg        {0.85, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
22107821949aSmrg        {0.86, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
22117821949aSmrg        {0.87, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
22127821949aSmrg        {0.88, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
22137821949aSmrg        {0.89, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
22147821949aSmrg        {0.90, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
22157821949aSmrg        {0.91, {{ 3,    26,  3,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
22167821949aSmrg        {0.92, {{ 2,    28,  2,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
22177821949aSmrg        {0.93, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
22187821949aSmrg        {0.94, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
22197821949aSmrg        {0.95, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
22207821949aSmrg        {0.96, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
22217821949aSmrg        {0.97, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
22227821949aSmrg        {0.98, {{ 1,    30,  1,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
22237821949aSmrg        {0.99, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }},
22247821949aSmrg        {1.00, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }}
22257821949aSmrg    };
22267821949aSmrg
22277821949aSmrgvoid
22287821949aSmrgRADEONCopyData(
22297821949aSmrg  ScrnInfoPtr pScrn,
22307821949aSmrg  unsigned char *src,
22317821949aSmrg  unsigned char *dst,
22327821949aSmrg  unsigned int srcPitch,
22337821949aSmrg  unsigned int dstPitch,
22347821949aSmrg  unsigned int h,
22357821949aSmrg  unsigned int w,
22367821949aSmrg  unsigned int bpp
22377821949aSmrg){
22387821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
22397821949aSmrg
22407821949aSmrg    /* Get the byte-swapping right for big endian systems */
22417821949aSmrg    if ( bpp == 2 ) {
22427821949aSmrg	w *= 2;
22437821949aSmrg	bpp = 1;
22447821949aSmrg    }
22457821949aSmrg
22467821949aSmrg#ifdef XF86DRI
22477821949aSmrg
22487821949aSmrg    if ( info->directRenderingEnabled && info->DMAForXv )
22497821949aSmrg    {
22507821949aSmrg	uint8_t *buf;
22517821949aSmrg	uint32_t bufPitch, dstPitchOff;
22527821949aSmrg	int x, y;
22537821949aSmrg	unsigned int hpass;
22547821949aSmrg
22557821949aSmrg	RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y );
22567821949aSmrg
22577821949aSmrg	while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch,
22587821949aSmrg					   x, &y, &h, &hpass )) )
22597821949aSmrg	{
22607821949aSmrg	    RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch,
22617821949aSmrg					srcPitch );
22627821949aSmrg	    src += hpass * srcPitch;
22637821949aSmrg	}
22647821949aSmrg
22657821949aSmrg	FLUSH_RING();
22667821949aSmrg
22677821949aSmrg	return;
22687821949aSmrg    }
22697821949aSmrg    else
22707821949aSmrg#endif /* XF86DRI */
22717821949aSmrg    {
22727821949aSmrg	int swap = RADEON_HOST_DATA_SWAP_NONE;
22737821949aSmrg
22747821949aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
22757821949aSmrg	if (info->kms_enabled) {
22767821949aSmrg	    switch(bpp) {
22777821949aSmrg	    case 2:
22787821949aSmrg		swap = RADEON_HOST_DATA_SWAP_16BIT;
22797821949aSmrg		break;
22807821949aSmrg	    case 4:
22817821949aSmrg		swap = RADEON_HOST_DATA_SWAP_32BIT;
22827821949aSmrg		break;
22837821949aSmrg	    }
22847821949aSmrg	} else {
22857821949aSmrg	    switch (pScrn->bitsPerPixel) {
22867821949aSmrg	    case 16:
22877821949aSmrg		swap = RADEON_HOST_DATA_SWAP_16BIT;
22887821949aSmrg		break;
22897821949aSmrg	    case 32:
22907821949aSmrg		swap = RADEON_HOST_DATA_SWAP_32BIT;
22917821949aSmrg		break;
22927821949aSmrg	    }
22937821949aSmrg	}
22947821949aSmrg#endif
22957821949aSmrg
22967821949aSmrg	w *= bpp;
22977821949aSmrg
22987821949aSmrg	if (dstPitch == w && dstPitch == srcPitch)
22997821949aSmrg	    RADEONCopySwap(dst, src, h * dstPitch, swap);
23007821949aSmrg	else {
23017821949aSmrg	    while (h--) {
23027821949aSmrg		RADEONCopySwap(dst, src, w, swap);
23037821949aSmrg		src += srcPitch;
23047821949aSmrg		dst += dstPitch;
23057821949aSmrg	    }
23067821949aSmrg	}
23077821949aSmrg    }
23087821949aSmrg}
23097821949aSmrg
23107821949aSmrgstatic void
23117821949aSmrgRADEONCopyRGB24Data(
23127821949aSmrg  ScrnInfoPtr pScrn,
23137821949aSmrg  unsigned char *src,
23147821949aSmrg  unsigned char *dst,
23157821949aSmrg  unsigned int srcPitch,
23167821949aSmrg  unsigned int dstPitch,
23177821949aSmrg  unsigned int h,
23187821949aSmrg  unsigned int w
23197821949aSmrg){
23207821949aSmrg    uint32_t *dptr;
23217821949aSmrg    uint8_t *sptr;
23227821949aSmrg    int i,j;
23237821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
23247821949aSmrg#ifdef XF86DRI
23257821949aSmrg
23267821949aSmrg    if ( info->directRenderingEnabled && info->DMAForXv )
23277821949aSmrg    {
23287821949aSmrg	uint32_t bufPitch, dstPitchOff;
23297821949aSmrg	int x, y;
23307821949aSmrg	unsigned int hpass;
23317821949aSmrg
23327821949aSmrg	RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y );
23337821949aSmrg
23347821949aSmrg	while ( (dptr = ( uint32_t* )RADEONHostDataBlit( pScrn, 4, w, dstPitchOff,
23357821949aSmrg						       &bufPitch, x, &y, &h,
23367821949aSmrg						       &hpass )) )
23377821949aSmrg	{
23387821949aSmrg	    for( j = 0; j < hpass; j++ )
23397821949aSmrg	    {
23407821949aSmrg		sptr = src;
23417821949aSmrg
23427821949aSmrg		for ( i = 0 ; i < w; i++, sptr += 3 )
23437821949aSmrg		{
23447821949aSmrg		    dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0];
23457821949aSmrg		}
23467821949aSmrg
23477821949aSmrg		src += srcPitch;
23487821949aSmrg		dptr += bufPitch / 4;
23497821949aSmrg	    }
23507821949aSmrg	}
23517821949aSmrg
23527821949aSmrg	FLUSH_RING();
23537821949aSmrg
23547821949aSmrg	return;
23557821949aSmrg    }
23567821949aSmrg    else
23577821949aSmrg#endif /* XF86DRI */
23587821949aSmrg    {
23597821949aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
23607821949aSmrg	unsigned char *RADEONMMIO = info->MMIO;
23617821949aSmrg
23627821949aSmrg	if (!info->kms_enabled)
23637821949aSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
23647821949aSmrg		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
23657821949aSmrg#endif
23667821949aSmrg
23677821949aSmrg	for (j = 0; j < h; j++) {
23687821949aSmrg	    dptr = (uint32_t *)(dst + j * dstPitch);
23697821949aSmrg	    sptr = src + j * srcPitch;
23707821949aSmrg
23717821949aSmrg	    for (i = 0; i < w; i++, sptr += 3) {
23727821949aSmrg		dptr[i] = cpu_to_le32((sptr[2] << 16) | (sptr[1] << 8) | sptr[0]);
23737821949aSmrg	    }
23747821949aSmrg	}
23757821949aSmrg
23767821949aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
23777821949aSmrg	if (!info->kms_enabled) {
23787821949aSmrg	    /* restore byte swapping */
23797821949aSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
23807821949aSmrg	}
23817821949aSmrg#endif
23827821949aSmrg    }
23837821949aSmrg}
23847821949aSmrg
23857821949aSmrg
23867821949aSmrg#ifdef XF86DRI
23877821949aSmrgstatic void RADEON_420_422(
23887821949aSmrg    unsigned int *d,
23897821949aSmrg    unsigned char *s1,
23907821949aSmrg    unsigned char *s2,
23917821949aSmrg    unsigned char *s3,
23927821949aSmrg    unsigned int n
23937821949aSmrg)
23947821949aSmrg{
23957821949aSmrg    while ( n ) {
23967821949aSmrg	*(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
23977821949aSmrg	s1+=2; s2++; s3++;
23987821949aSmrg	n--;
23997821949aSmrg    }
24007821949aSmrg}
24017821949aSmrg#endif
24027821949aSmrg
24037821949aSmrgvoid
24047821949aSmrgRADEONCopyMungedData(
24057821949aSmrg   ScrnInfoPtr pScrn,
24067821949aSmrg   unsigned char *src1,
24077821949aSmrg   unsigned char *src2,
24087821949aSmrg   unsigned char *src3,
24097821949aSmrg   unsigned char *dst1,
24107821949aSmrg   unsigned int srcPitch,
24117821949aSmrg   unsigned int srcPitch2,
24127821949aSmrg   unsigned int dstPitch,
24137821949aSmrg   unsigned int h,
24147821949aSmrg   unsigned int w
24157821949aSmrg){
24167821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
24177821949aSmrg#ifdef XF86DRI
24187821949aSmrg
24197821949aSmrg    if ( info->directRenderingEnabled && info->DMAForXv )
24207821949aSmrg    {
24217821949aSmrg	uint8_t *buf;
24227821949aSmrg	uint32_t y = 0, bufPitch, dstPitchOff;
24237821949aSmrg	int blitX, blitY;
24247821949aSmrg	unsigned int hpass;
24257821949aSmrg
24267821949aSmrg	/* XXX Fix endian flip on R300 */
24277821949aSmrg
24287821949aSmrg	RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY );
24297821949aSmrg
24307821949aSmrg	while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch,
24317821949aSmrg					   blitX, &blitY, &h, &hpass )) )
24327821949aSmrg	{
24337821949aSmrg	    while ( hpass-- )
24347821949aSmrg	    {
24357821949aSmrg		RADEON_420_422( (unsigned int *) buf, src1, src2, src3,
24367821949aSmrg				bufPitch / 4 );
24377821949aSmrg		src1 += srcPitch;
24387821949aSmrg		if ( y & 1 )
24397821949aSmrg		{
24407821949aSmrg		    src2 += srcPitch2;
24417821949aSmrg		    src3 += srcPitch2;
24427821949aSmrg		}
24437821949aSmrg		buf += bufPitch;
24447821949aSmrg		y++;
24457821949aSmrg	    }
24467821949aSmrg	}
24477821949aSmrg
24487821949aSmrg	FLUSH_RING();
24497821949aSmrg    }
24507821949aSmrg    else
24517821949aSmrg#endif /* XF86DRI */
24527821949aSmrg    {
24537821949aSmrg	uint32_t *dst;
24547821949aSmrg	uint8_t *s1, *s2, *s3;
24557821949aSmrg	int i, j;
24567821949aSmrg
24577821949aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
24587821949aSmrg	unsigned char *RADEONMMIO = info->MMIO;
24597821949aSmrg
24607821949aSmrg	if (!info->kms_enabled)
24617821949aSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
24627821949aSmrg		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
24637821949aSmrg#endif
24647821949aSmrg
24657821949aSmrg	w /= 2;
24667821949aSmrg
24677821949aSmrg	for( j = 0; j < h; j++ )
24687821949aSmrg	{
24697821949aSmrg	    dst = (pointer)dst1;
24707821949aSmrg	    s1 = src1;  s2 = src2;  s3 = src3;
24717821949aSmrg	    i = w;
24727821949aSmrg	    while( i > 4 )
24737821949aSmrg	    {
24747821949aSmrg		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
24757821949aSmrg		dst[1] = cpu_to_le32(s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24));
24767821949aSmrg		dst[2] = cpu_to_le32(s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24));
24777821949aSmrg		dst[3] = cpu_to_le32(s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24));
24787821949aSmrg		dst += 4; s2 += 4; s3 += 4; s1 += 8;
24797821949aSmrg		i -= 4;
24807821949aSmrg	    }
24817821949aSmrg	    while( i-- )
24827821949aSmrg	    {
24837821949aSmrg		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
24847821949aSmrg		dst++; s2++; s3++;
24857821949aSmrg		s1 += 2;
24867821949aSmrg	    }
24877821949aSmrg
24887821949aSmrg	    dst1 += dstPitch;
24897821949aSmrg	    src1 += srcPitch;
24907821949aSmrg	    if( j & 1 )
24917821949aSmrg	    {
24927821949aSmrg		src2 += srcPitch2;
24937821949aSmrg		src3 += srcPitch2;
24947821949aSmrg	    }
24957821949aSmrg	}
24967821949aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
24977821949aSmrg	if (!info->kms_enabled) {
24987821949aSmrg	    /* restore byte swapping */
24997821949aSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
25007821949aSmrg	}
25017821949aSmrg#endif
25027821949aSmrg    }
25037821949aSmrg}
25047821949aSmrg
25057821949aSmrgstatic void
25067821949aSmrgRADEONDisplayVideo(
25077821949aSmrg    ScrnInfoPtr pScrn,
25087821949aSmrg    xf86CrtcPtr crtc,
25097821949aSmrg    RADEONPortPrivPtr pPriv,
25107821949aSmrg    int id,
25117821949aSmrg    int base_offset,
25127821949aSmrg    int offset1, int offset2,
25137821949aSmrg    int offset3, int offset4,
25147821949aSmrg    int offset5, int offset6,
25157821949aSmrg    short width, short height,
25167821949aSmrg    int pitch,
25177821949aSmrg    int left, int right, int top,
25187821949aSmrg    BoxPtr dstBox,
25197821949aSmrg    short src_w, short src_h,
25207821949aSmrg    short drw_w, short drw_h,
25217821949aSmrg    int deinterlacing_method
25227821949aSmrg){
25237821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
25247821949aSmrg    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
25257821949aSmrg    unsigned char *RADEONMMIO = info->MMIO;
25267821949aSmrg    uint32_t v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp;
25277821949aSmrg    double h_inc_d;
25287821949aSmrg    int p1_h_accum_init, p23_h_accum_init;
25297821949aSmrg    int p1_v_accum_init, p23_v_accum_init;
25307821949aSmrg    int p23_blank_lines;
25317821949aSmrg    int ecp_div;
25327821949aSmrg    int v_inc_shift;
25337821949aSmrg    int y_mult;
25347821949aSmrg    int x_off;
25357821949aSmrg    int y_off;
25367821949aSmrg    uint32_t scaler_src;
25377821949aSmrg    uint32_t dot_clock;
25387821949aSmrg    int is_rgb;
25397821949aSmrg    int is_planar;
25407821949aSmrg    int i;
25417821949aSmrg    uint32_t scale_cntl;
25427821949aSmrg    double dsr;
25437821949aSmrg    int tap_set;
25447821949aSmrg    int predownscale=0;
25457821949aSmrg    int src_w_d;
25467821949aSmrg    int leftuv = 0;
25477821949aSmrg    DisplayModePtr mode;
25487821949aSmrg    RADEONOutputPrivatePtr radeon_output;
25497821949aSmrg    xf86OutputPtr output;
25507821949aSmrg    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
25517821949aSmrg
25527821949aSmrg    is_rgb=0; is_planar=0;
25537821949aSmrg    switch(id){
25547821949aSmrg        case FOURCC_I420:
25557821949aSmrg        case FOURCC_YV12:
25567821949aSmrg            is_planar=1;
25577821949aSmrg            break;
25587821949aSmrg        case FOURCC_RGBA32:
25597821949aSmrg        case FOURCC_RGB24:
25607821949aSmrg        case FOURCC_RGBT16:
25617821949aSmrg        case FOURCC_RGB16:
25627821949aSmrg            is_rgb=1;
25637821949aSmrg            break;
25647821949aSmrg        default:
25657821949aSmrg	    break;
25667821949aSmrg    }
25677821949aSmrg
25687821949aSmrg    /* Here we need to find ecp_div again, as the user may have switched resolutions
25697821949aSmrg       but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to
25707821949aSmrg       workarounds for chip erratas */
25717821949aSmrg
25727821949aSmrg    /* Figure out which head we are on for dot clock */
25737821949aSmrg    if (radeon_crtc->crtc_id == 1)
25747821949aSmrg        dot_clock = info->ModeReg->dot_clock_freq_2;
25757821949aSmrg    else
25767821949aSmrg        dot_clock = info->ModeReg->dot_clock_freq;
25777821949aSmrg
25787821949aSmrg    if (dot_clock < 17500)
25797821949aSmrg        ecp_div = 0;
25807821949aSmrg    else
25817821949aSmrg	ecp_div = 1;
25827821949aSmrg
25837821949aSmrg    if (ecp_div != info->ecp_div) {
25847821949aSmrg	info->ecp_div = ecp_div;
25857821949aSmrg	OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
25867821949aSmrg	   (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
25877821949aSmrg    }
25887821949aSmrg
25897821949aSmrg    /* I suspect we may need a usleep after writing to the PLL.  if you play a video too soon
25907821949aSmrg       after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
25917821949aSmrg       on the right edge video output.
25927821949aSmrg       Is this still the case? Might have been chips which need the errata,
25937821949aSmrg       there is now plenty of usleep after INPLL/OUTPLL for those...*/
25947821949aSmrg
25957821949aSmrg    v_inc_shift = 20;
25967821949aSmrg    y_mult = 1;
25977821949aSmrg
25987821949aSmrg    mode = &crtc->mode;
25997821949aSmrg
26007821949aSmrg    if (mode->Flags & V_INTERLACE)
26017821949aSmrg	v_inc_shift++;
26027821949aSmrg    if (mode->Flags & V_DBLSCAN) {
26037821949aSmrg	v_inc_shift--;
26047821949aSmrg	y_mult = 2;
26057821949aSmrg    }
26067821949aSmrg
26077821949aSmrg    v_inc = (src_h << v_inc_shift) / drw_h;
26087821949aSmrg
26097821949aSmrg    for (i = 0; i < xf86_config->num_output; i++) {
26107821949aSmrg	output = xf86_config->output[i];
26117821949aSmrg	if (output->crtc == crtc) {
26127821949aSmrg	    radeon_output = output->driver_private;
26137821949aSmrg	    if (radeon_output->Flags & RADEON_USE_RMX)
26147821949aSmrg		v_inc = ((src_h * mode->CrtcVDisplay /
26157821949aSmrg			  radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h;
26167821949aSmrg	    break;
26177821949aSmrg	}
26187821949aSmrg    }
26197821949aSmrg
26207821949aSmrg    h_inc = (1 << (12 + ecp_div));
26217821949aSmrg
26227821949aSmrg    step_by_y = 1;
26237821949aSmrg    step_by_uv = step_by_y;
26247821949aSmrg
26257821949aSmrg    src_w_d = src_w;
26267821949aSmrg#if 0
26277821949aSmrg    /* XXX this does not appear to work */
26287821949aSmrg    /* if the source width was larger than what would fit in overlay scaler increase step_by values */
26297821949aSmrg    i=src_w;
26307821949aSmrg    while(i>info->overlay_scaler_buffer_width){
26317821949aSmrg	step_by_y++;
26327821949aSmrg	step_by_uv++;
26337821949aSmrg	h_inc >>=1;
26347821949aSmrg	i=i/2;
26357821949aSmrg	}
26367821949aSmrg#else
26377821949aSmrg    /* predownscale instead (yes this hurts quality) - will only work for widths up
26387821949aSmrg       to 2 times the overlay_scaler_buffer_width, should be enough */
26397821949aSmrg    if (src_w_d > info->overlay_scaler_buffer_width) {
26407821949aSmrg	src_w_d /= 2; /* odd widths? */
26417821949aSmrg	predownscale = 1;
26427821949aSmrg    }
26437821949aSmrg#endif
26447821949aSmrg
26457821949aSmrg    h_inc_d = src_w_d;
26467821949aSmrg    h_inc_d = h_inc_d/drw_w;
26477821949aSmrg    /* we could do a tad better  - but why
26487821949aSmrg       bother when this concerns downscaling and the code is so much more
26497821949aSmrg       hairy */
26507821949aSmrg    while(h_inc*h_inc_d >= (2 << 12)) {
26517821949aSmrg        if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){
26527821949aSmrg                step_by_uv = step_by_y+1;
26537821949aSmrg                break;
26547821949aSmrg                }
26557821949aSmrg        step_by_y++;
26567821949aSmrg        step_by_uv = step_by_y;
26577821949aSmrg        h_inc >>= 1;
26587821949aSmrg    }
26597821949aSmrg
26607821949aSmrg    h_inc_uv = h_inc>>(step_by_uv-step_by_y);
26617821949aSmrg    h_inc = h_inc * h_inc_d;
26627821949aSmrg    h_inc_uv = h_inc_uv * h_inc_d;
26637821949aSmrg    /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit
26647821949aSmrg       in the buffer for 2 tap filtering */
26657821949aSmrg    /* the only place it is documented in is in ATI source code */
26667821949aSmrg    /* we need twice as much space for 4 tap filtering.. */
26677821949aSmrg    /* under special circumstances turn on 4 tap filtering */
26687821949aSmrg    /* disable this code for now as it has a DISASTROUS effect on image quality when upscaling
26697821949aSmrg       at least on rv250 (only as long as the drw_w*2 <=... requirement is still met of course) */
26707821949aSmrg#if 0
26717821949aSmrg    if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12))
26727821949aSmrg       && (deinterlacing_method!=METHOD_WEAVE)
26737821949aSmrg       && (drw_w*2 <= info->overlay_scaler_buffer_width)){
26747821949aSmrg        step_by_y=0;
26757821949aSmrg        step_by_uv=1;
26767821949aSmrg        h_inc_uv = h_inc;
26777821949aSmrg        }
26787821949aSmrg#endif
26797821949aSmrg
26807821949aSmrg    /* Make the overlay base address as close to the buffers as possible to
26817821949aSmrg     * prevent the buffer offsets from exceeding the hardware limit of 128 MB.
26827821949aSmrg     * The base address must be aligned to a multiple of 4 MB.
26837821949aSmrg     */
26847821949aSmrg    base_offset = ((info->fbLocation + base_offset) & (~0 << 22)) -
26857821949aSmrg	info->fbLocation;
26867821949aSmrg
26877821949aSmrg    offset1 -= base_offset;
26887821949aSmrg    offset2 -= base_offset;
26897821949aSmrg    offset3 -= base_offset;
26907821949aSmrg    offset4 -= base_offset;
26917821949aSmrg    offset5 -= base_offset;
26927821949aSmrg    offset6 -= base_offset;
26937821949aSmrg
26947821949aSmrg    /* keep everything in 16.16 */
26957821949aSmrg
26967821949aSmrg    if (is_planar) {
26977821949aSmrg	offset1 += ((left >> 16) & ~15);
26987821949aSmrg	offset2 += ((left >> 16) & ~31) >> 1;
26997821949aSmrg	offset3 += ((left >> 16) & ~31) >> 1;
27007821949aSmrg	offset4 += ((left >> 16) & ~15);
27017821949aSmrg	offset5 += ((left >> 16) & ~31) >> 1;
27027821949aSmrg	offset6 += ((left >> 16) & ~31) >> 1;
27037821949aSmrg	offset2 |= RADEON_VIF_BUF0_PITCH_SEL;
27047821949aSmrg	offset3 |= RADEON_VIF_BUF0_PITCH_SEL;
27057821949aSmrg	offset5 |= RADEON_VIF_BUF0_PITCH_SEL;
27067821949aSmrg	offset6 |= RADEON_VIF_BUF0_PITCH_SEL;
27077821949aSmrg    }
27087821949aSmrg    else {
27097821949aSmrg	/* is this really correct for non-2-byte formats? */
27107821949aSmrg	offset1 += ((left >> 16) & ~7) << 1;
27117821949aSmrg	offset2 += ((left >> 16) & ~7) << 1;
27127821949aSmrg	offset3 += ((left >> 16) & ~7) << 1;
27137821949aSmrg	offset4 += ((left >> 16) & ~7) << 1;
27147821949aSmrg	offset5 += ((left >> 16) & ~7) << 1;
27157821949aSmrg	offset6 += ((left >> 16) & ~7) << 1;
27167821949aSmrg    }
27177821949aSmrg
27187821949aSmrg    tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
27197821949aSmrg    p1_h_accum_init = ((tmp <<  4) & 0x000f8000) |
27207821949aSmrg		      ((tmp << 12) & 0xf0000000);
27217821949aSmrg
27227821949aSmrg    tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2);
27237821949aSmrg    p23_h_accum_init = ((tmp <<  4) & 0x000f8000) |
27247821949aSmrg		       ((tmp << 12) & 0x70000000);
27257821949aSmrg
27267821949aSmrg    tmp = (top & 0x0000ffff) + 0x00018000;
27277821949aSmrg    p1_v_accum_init = ((tmp << 4) & 0x03ff8000) |
27287821949aSmrg    	(((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01);
27297821949aSmrg
27307821949aSmrg    if (is_planar) {
27317821949aSmrg	p23_v_accum_init = ((tmp << 4) & 0x03ff8000) |
27327821949aSmrg	    ((deinterlacing_method != METHOD_WEAVE) ? 0x03 : 0x01);
27337821949aSmrg	p23_blank_lines = (((src_h >> 1) - 1) << 16);
27347821949aSmrg    }
27357821949aSmrg    else {
27367821949aSmrg	p23_v_accum_init = 0;
27377821949aSmrg	p23_blank_lines = 0;
27387821949aSmrg    }
27397821949aSmrg
27407821949aSmrg    if (is_planar) {
27417821949aSmrg	leftuv = ((left >> 16) >> 1) & 15;
27427821949aSmrg	left = (left >> 16) & 15;
27437821949aSmrg    }
27447821949aSmrg    else {
27457821949aSmrg	left = (left >> 16) & 7;
27467821949aSmrg	if (!is_rgb)
27477821949aSmrg	    leftuv = left >> 1;
27487821949aSmrg    }
27497821949aSmrg
27507821949aSmrg    RADEONWaitForFifo(pScrn, 2);
27517821949aSmrg    OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK);
27527821949aSmrg    if (info->accelOn) RADEON_SYNC(info, pScrn);
27537821949aSmrg    while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
27547821949aSmrg
27557821949aSmrg    RADEONWaitForFifo(pScrn, 10);
27567821949aSmrg    OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16));
27577821949aSmrg    OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) |
27587821949aSmrg	predownscale << 4 | predownscale << 12);
27597821949aSmrg
27607821949aSmrg    x_off = 8;
27617821949aSmrg    y_off = 0;
27627821949aSmrg
27637821949aSmrg    if (IS_R300_VARIANT ||
27647821949aSmrg        (info->ChipFamily == CHIP_FAMILY_R200))
27657821949aSmrg	x_off = 0;
27667821949aSmrg
27677821949aSmrg    /* needed to make the overlay work on crtc1 in leftof and above modes */
27687821949aSmrg    /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */
27697821949aSmrg    /*
27707821949aSmrg    if (srel == radeonLeftOf) {
27717821949aSmrg	x_off -= mode->CrtcHDisplay;
27727821949aSmrg    }
27737821949aSmrg    if (srel == radeonAbove) {
27747821949aSmrg	y_off -= mode->CrtcVDisplay;
27757821949aSmrg    }
27767821949aSmrg    */
27777821949aSmrg
27787821949aSmrg    /* Put the hardware overlay on CRTC2:
27797821949aSmrg     *
27807821949aSmrg     * Since one hardware overlay can not be displayed on two heads
27817821949aSmrg     * at the same time, we might need to consider using software
27827821949aSmrg     * rendering for the second head.
27837821949aSmrg     */
27847821949aSmrg
27857821949aSmrg    if (radeon_crtc->crtc_id == 1) {
27867821949aSmrg        x_off = 0;
27877821949aSmrg        OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
27887821949aSmrg                                      ((dstBox->y1*y_mult) << 16)));
27897821949aSmrg        OUTREG(RADEON_OV1_Y_X_END,   ((dstBox->x2 + x_off) |
27907821949aSmrg                                      ((dstBox->y2*y_mult) << 16)));
27917821949aSmrg        scaler_src = RADEON_SCALER_CRTC_SEL;
27927821949aSmrg    } else {
27937821949aSmrg	OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) |
27947821949aSmrg				      (((dstBox->y1*y_mult) + y_off) << 16)));
27957821949aSmrg	OUTREG(RADEON_OV0_Y_X_END,   ((dstBox->x2 + x_off) |
27967821949aSmrg				      (((dstBox->y2*y_mult) + y_off) << 16)));
27977821949aSmrg	scaler_src = 0;
27987821949aSmrg    }
27997821949aSmrg
28007821949aSmrg    /* program the tap coefficients for better downscaling quality.
28017821949aSmrg       Could do slightly better by using hardcoded coefficients for one axis
28027821949aSmrg       in case only the other axis is downscaled (see RADEON_OV0_FILTER_CNTL) */
28037821949aSmrg    dsr=(double)(1<<0xC)/h_inc;
28047821949aSmrg    if(dsr<0.25)dsr=0.25;
28057821949aSmrg    if(dsr>1.0)dsr=1.0;
28067821949aSmrg    tap_set=(int)((dsr-0.25)*100);
28077821949aSmrg    for(i=0;i<5;i++){
28087821949aSmrg	    OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) |
28097821949aSmrg	    	((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) |
28107821949aSmrg	    	((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) |
28117821949aSmrg	    	((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24));
28127821949aSmrg		}
28137821949aSmrg
28147821949aSmrg    RADEONWaitForFifo(pScrn, 11);
28157821949aSmrg    OUTREG(RADEON_OV0_V_INC, v_inc);
28167821949aSmrg    OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));
28177821949aSmrg    OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | p23_blank_lines);
28187821949aSmrg    OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch);
28197821949aSmrg    OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch);
28207821949aSmrg    OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16));
28217821949aSmrg    if (!is_rgb)
28227821949aSmrg	src_w >>= 1;
28237821949aSmrg    OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
28247821949aSmrg    OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
28257821949aSmrg    if (info->ModeReg->ov0_base_addr != (info->fbLocation + base_offset)) {
28267821949aSmrg	ErrorF("Changing OV0_BASE_ADDR from 0x%08x to 0x%08x\n",
28277821949aSmrg	       info->ModeReg->ov0_base_addr, (uint32_t)info->fbLocation + base_offset);
28287821949aSmrg	info->ModeReg->ov0_base_addr = info->fbLocation + base_offset;
28297821949aSmrg	OUTREG(RADEON_OV0_BASE_ADDR, info->ModeReg->ov0_base_addr);
28307821949aSmrg    }
28317821949aSmrg    OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1);
28327821949aSmrg    OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2);
28337821949aSmrg    OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3);
28347821949aSmrg
28357821949aSmrg    RADEONWaitForFifo(pScrn, 9);
28367821949aSmrg    OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4);
28377821949aSmrg    OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset5);
28387821949aSmrg    OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset6);
28397821949aSmrg    OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
28407821949aSmrg    OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
28417821949aSmrg    OUTREG(RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init);
28427821949aSmrg    OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
28437821949aSmrg
28447821949aSmrg   scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER
28457821949aSmrg        | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16) | scaler_src;
28467821949aSmrg   switch(id){
28477821949aSmrg        case FOURCC_UYVY:
28487821949aSmrg		scale_cntl |= RADEON_SCALER_SOURCE_YVYU422;
28497821949aSmrg		break;
28507821949aSmrg        case FOURCC_RGB24:
28517821949aSmrg        case FOURCC_RGBA32:
28527821949aSmrg		scale_cntl |= RADEON_SCALER_SOURCE_32BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
28537821949aSmrg		break;
28547821949aSmrg        case FOURCC_RGB16:
28557821949aSmrg		scale_cntl |= RADEON_SCALER_SOURCE_16BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
28567821949aSmrg		break;
28577821949aSmrg        case FOURCC_RGBT16:
28587821949aSmrg		scale_cntl |= RADEON_SCALER_SOURCE_15BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
28597821949aSmrg		break;
28607821949aSmrg        case FOURCC_YV12:
28617821949aSmrg        case FOURCC_I420:
28627821949aSmrg		scale_cntl |= RADEON_SCALER_SOURCE_YUV12;
28637821949aSmrg		break;
28647821949aSmrg        case FOURCC_YUY2:
28657821949aSmrg        default:
28667821949aSmrg		scale_cntl |= RADEON_SCALER_SOURCE_VYUY422
28677821949aSmrg			| ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0);
28687821949aSmrg		break;
28697821949aSmrg    }
28707821949aSmrg
28717821949aSmrg    if (info->ChipFamily < CHIP_FAMILY_R200) {
28727821949aSmrg	scale_cntl &= ~RADEON_SCALER_GAMMA_SEL_MASK;
28737821949aSmrg	scale_cntl |= ((RADEONTranslateUserGamma(pPriv->gamma)) << 5);
28747821949aSmrg    }
28757821949aSmrg
28767821949aSmrg    OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl);
28777821949aSmrg    OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
28787821949aSmrg}
28797821949aSmrg
28807821949aSmrg
28817821949aSmrgstatic void
28827821949aSmrgRADEONFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes)
28837821949aSmrg{
28847821949aSmrg#if HAVE_XV_DRAWABLE_HELPER
28857821949aSmrg    xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes);
28867821949aSmrg#else
28877821949aSmrg    xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes);
28887821949aSmrg#endif
28897821949aSmrg}
28907821949aSmrg
28917821949aSmrg
28927821949aSmrgstatic int
28937821949aSmrgRADEONPutImage(
28947821949aSmrg  ScrnInfoPtr pScrn,
28957821949aSmrg  short src_x, short src_y,
28967821949aSmrg  short drw_x, short drw_y,
28977821949aSmrg  short src_w, short src_h,
28987821949aSmrg  short drw_w, short drw_h,
28997821949aSmrg  int id, unsigned char* buf,
29007821949aSmrg  short width, short height,
29017821949aSmrg  Bool Sync,
29027821949aSmrg  RegionPtr clipBoxes, pointer data,
29037821949aSmrg  DrawablePtr pDraw
29047821949aSmrg){
29057821949aSmrg   RADEONInfoPtr info = RADEONPTR(pScrn);
29067821949aSmrg   RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
29077821949aSmrg   INT32 xa, xb, ya, yb;
29087821949aSmrg   unsigned char *dst_start;
29097821949aSmrg   int new_size, offset, s2offset, s3offset;
29107821949aSmrg   int srcPitch, srcPitch2, dstPitch;
29117821949aSmrg   int d2line, d3line;
29127821949aSmrg   int top, left, npixels, nlines, bpp;
29137821949aSmrg   int idconv = id;
29147821949aSmrg   BoxRec dstBox;
29157821949aSmrg   uint32_t tmp;
29167821949aSmrg   xf86CrtcPtr crtc;
29177821949aSmrg
29187821949aSmrg   /*
29197821949aSmrg    * s2offset, s3offset - byte offsets into U and V plane of the
29207821949aSmrg    *                      source where copying starts.  Y plane is
29217821949aSmrg    *                      done by editing "buf".
29227821949aSmrg    *
29237821949aSmrg    * offset - byte offset to the first line of the destination.
29247821949aSmrg    *
29257821949aSmrg    * dst_start - byte address to the first displayed pel.
29267821949aSmrg    *
29277821949aSmrg    */
29287821949aSmrg
29297821949aSmrg   /* make the compiler happy */
29307821949aSmrg   s2offset = s3offset = srcPitch2 = 0;
29317821949aSmrg   d2line = d3line = 0;
29327821949aSmrg
29337821949aSmrg   if(src_w > (drw_w << 4))
29347821949aSmrg	drw_w = src_w >> 4;
29357821949aSmrg   if(src_h > (drw_h << 4))
29367821949aSmrg	drw_h = src_h >> 4;
29377821949aSmrg
29387821949aSmrg   /* Clip */
29397821949aSmrg   xa = src_x;
29407821949aSmrg   xb = src_x + src_w;
29417821949aSmrg   ya = src_y;
29427821949aSmrg   yb = src_y + src_h;
29437821949aSmrg
29447821949aSmrg   dstBox.x1 = drw_x;
29457821949aSmrg   dstBox.x2 = drw_x + drw_w;
29467821949aSmrg   dstBox.y1 = drw_y;
29477821949aSmrg   dstBox.y2 = drw_y + drw_h;
29487821949aSmrg
29497821949aSmrg   if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
29507821949aSmrg			       &dstBox, &xa, &xb, &ya, &yb,
29517821949aSmrg			       clipBoxes, width, height))
29527821949aSmrg       return Success;
29537821949aSmrg
29547821949aSmrg   if (!crtc) {
29557821949aSmrg       if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
29567821949aSmrg	   unsigned char *RADEONMMIO = info->MMIO;
29577821949aSmrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
29587821949aSmrg	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
29597821949aSmrg       }
29607821949aSmrg       return Success;
29617821949aSmrg   }
29627821949aSmrg
29637821949aSmrg   dstBox.x1 -= crtc->x;
29647821949aSmrg   dstBox.x2 -= crtc->x;
29657821949aSmrg   dstBox.y1 -= crtc->y;
29667821949aSmrg   dstBox.y2 -= crtc->y;
29677821949aSmrg
29687821949aSmrg   bpp = pScrn->bitsPerPixel >> 3;
29697821949aSmrg
29707821949aSmrg   switch(id) {
29717821949aSmrg   case FOURCC_RGB24:
29727821949aSmrg	dstPitch = width * 4;
29737821949aSmrg	srcPitch = width * 3;
29747821949aSmrg	break;
29757821949aSmrg   case FOURCC_RGBA32:
29767821949aSmrg	dstPitch = width * 4;
29777821949aSmrg	srcPitch = width * 4;
29787821949aSmrg	break;
29797821949aSmrg   case FOURCC_RGB16:
29807821949aSmrg   case FOURCC_RGBT16:
29817821949aSmrg	dstPitch = width * 2;
29827821949aSmrg	srcPitch = RADEON_ALIGN(width * 2, 4);
29837821949aSmrg	break;
29847821949aSmrg   case FOURCC_YV12:
29857821949aSmrg   case FOURCC_I420:
29867821949aSmrg	/* it seems rs4xx chips (all of them???) either can't handle planar
29877821949aSmrg	   yuv at all or would need some unknown different setup. */
29887821949aSmrg       if ((info->ChipFamily != CHIP_FAMILY_RS400) &&
29897821949aSmrg	   (info->ChipFamily != CHIP_FAMILY_RS480)) {
29907821949aSmrg	    /* need 16bytes alignment for u,v plane, so 2 times that for width
29917821949aSmrg	       but blitter needs 64bytes alignment. 128byte is a waste but dstpitch
29927821949aSmrg	       for uv planes needs to be dstpitch yplane >> 1 for now. */
29937821949aSmrg	    dstPitch = (RADEON_ALIGN(width, 128));
29947821949aSmrg	    srcPitch = RADEON_ALIGN(width, 4);
29957821949aSmrg	}
29967821949aSmrg	else {
29977821949aSmrg	    dstPitch = width * 2;
29987821949aSmrg	    srcPitch = RADEON_ALIGN(width, 4);
29997821949aSmrg	    idconv = FOURCC_YUY2;
30007821949aSmrg	}
30017821949aSmrg	break;
30027821949aSmrg   case FOURCC_UYVY:
30037821949aSmrg   case FOURCC_YUY2:
30047821949aSmrg   default:
30057821949aSmrg	dstPitch = width * 2;
30067821949aSmrg	srcPitch = width * 2;
30077821949aSmrg	break;
30087821949aSmrg   }
30097821949aSmrg
30107821949aSmrg#ifdef XF86DRI
30117821949aSmrg   if (info->directRenderingEnabled && info->DMAForXv) {
30127821949aSmrg       /* The upload blit only supports multiples of 64 bytes */
30137821949aSmrg       dstPitch = RADEON_ALIGN(dstPitch, 64);
30147821949aSmrg   } else
30157821949aSmrg#endif
30167821949aSmrg       /* The overlay only supports multiples of 16 bytes */
30177821949aSmrg       dstPitch = RADEON_ALIGN(dstPitch, 16);
30187821949aSmrg
30197821949aSmrg   new_size = dstPitch * height;
30207821949aSmrg   if (idconv == FOURCC_YV12 || id == FOURCC_I420) {
30217821949aSmrg      new_size += (dstPitch >> 1) * (RADEON_ALIGN(height, 2));
30227821949aSmrg   }
30237821949aSmrg   pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
30247821949aSmrg						       (pPriv->doubleBuffer ?
30257821949aSmrg						       (new_size * 2) : new_size), 64,
30267821949aSmrg						       RADEON_GEM_DOMAIN_VRAM);
30277821949aSmrg   if (pPriv->video_offset == 0)
30287821949aSmrg      return BadAlloc;
30297821949aSmrg
30307821949aSmrg   pPriv->currentBuffer ^= 1;
30317821949aSmrg
30327821949aSmrg    /* copy data */
30337821949aSmrg   top = ya >> 16;
30347821949aSmrg   left = (xa >> 16) & ~1;
30357821949aSmrg   npixels = ((xb + 0xffff) >> 16) - left;
30367821949aSmrg
30377821949aSmrg   offset = (pPriv->video_offset) + (top * dstPitch);
30387821949aSmrg
30397821949aSmrg   if(pPriv->doubleBuffer) {
30407821949aSmrg	unsigned char *RADEONMMIO = info->MMIO;
30417821949aSmrg
30427821949aSmrg	/* Wait for last flip to take effect */
30437821949aSmrg	while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK));
30447821949aSmrg
30457821949aSmrg	offset += pPriv->currentBuffer * new_size;
30467821949aSmrg   }
30477821949aSmrg
30487821949aSmrg   dst_start = info->FB + offset;
30497821949aSmrg
30507821949aSmrg   switch(id) {
30517821949aSmrg   case FOURCC_YV12:
30527821949aSmrg   case FOURCC_I420:
30537821949aSmrg	if (id == idconv) {
30547821949aSmrg	    /* meh. Such a mess just for someone who wants to watch half the video clipped */
30557821949aSmrg	    top &= ~1;
30567821949aSmrg	    /* odd number of pixels? That may not work correctly */
30577821949aSmrg	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
30587821949aSmrg	    /* odd number of lines? Maybe... */
30597821949aSmrg	    s2offset = srcPitch * (RADEON_ALIGN(height, 2));
30607821949aSmrg	    s3offset = s2offset + srcPitch2 * ((height + 1) >> 1);
30617821949aSmrg	    s2offset += (top >> 1) * srcPitch2 + (left >> 1);
30627821949aSmrg	    s3offset += (top >> 1) * srcPitch2 + (left >> 1);
30637821949aSmrg	    d2line = (height * dstPitch);
30647821949aSmrg	    d3line = d2line + ((height + 1) >> 1) * (dstPitch >> 1);
30657821949aSmrg	    nlines = ((yb + 0xffff) >> 16) - top;
30667821949aSmrg	    d2line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
30677821949aSmrg	    d3line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
30687821949aSmrg	    if(id == FOURCC_YV12) {
30697821949aSmrg		tmp = s2offset;
30707821949aSmrg		s2offset = s3offset;
30717821949aSmrg		s3offset = tmp;
30727821949aSmrg	    }
30737821949aSmrg	    RADEONCopyData(pScrn, buf + (top * srcPitch) + left, dst_start + left,
30747821949aSmrg		srcPitch, dstPitch, nlines, npixels, 1);
30757821949aSmrg	    RADEONCopyData(pScrn, buf + s2offset, dst_start + d2line + (left >> 1),
30767821949aSmrg		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
30777821949aSmrg	    RADEONCopyData(pScrn, buf + s3offset, dst_start + d3line + (left >> 1),
30787821949aSmrg		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
30797821949aSmrg	}
30807821949aSmrg	else {
30817821949aSmrg	    s2offset = srcPitch * height;
30827821949aSmrg	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
30837821949aSmrg	    s3offset = (srcPitch2 * (height >> 1)) + s2offset;
30847821949aSmrg	    top &= ~1;
30857821949aSmrg	    dst_start += left << 1;
30867821949aSmrg	    tmp = ((top >> 1) * srcPitch2) + (left >> 1);
30877821949aSmrg	    s2offset += tmp;
30887821949aSmrg	    s3offset += tmp;
30897821949aSmrg	    if(id == FOURCC_I420) {
30907821949aSmrg		tmp = s2offset;
30917821949aSmrg		s2offset = s3offset;
30927821949aSmrg		s3offset = tmp;
30937821949aSmrg	    }
30947821949aSmrg	    nlines = ((yb + 0xffff) >> 16) - top;
30957821949aSmrg	    RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left,
30967821949aSmrg				 buf + s2offset, buf + s3offset, dst_start,
30977821949aSmrg				 srcPitch, srcPitch2, dstPitch, nlines, npixels);
30987821949aSmrg	}
30997821949aSmrg	break;
31007821949aSmrg    case FOURCC_RGBT16:
31017821949aSmrg    case FOURCC_RGB16:
31027821949aSmrg    case FOURCC_UYVY:
31037821949aSmrg    case FOURCC_YUY2:
31047821949aSmrg    default:
31057821949aSmrg	left <<= 1;
31067821949aSmrg	buf += (top * srcPitch) + left;
31077821949aSmrg	nlines = ((yb + 0xffff) >> 16) - top;
31087821949aSmrg	dst_start += left;
31097821949aSmrg	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2);
31107821949aSmrg	break;
31117821949aSmrg    case FOURCC_RGBA32:
31127821949aSmrg	buf += (top * srcPitch) + left*4;
31137821949aSmrg	nlines = ((yb + 0xffff) >> 16) - top;
31147821949aSmrg	dst_start += left*4;
31157821949aSmrg	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4);
31167821949aSmrg    	break;
31177821949aSmrg    case FOURCC_RGB24:
31187821949aSmrg	buf += (top * srcPitch) + left*3;
31197821949aSmrg	nlines = ((yb + 0xffff) >> 16) - top;
31207821949aSmrg	dst_start += left*4;
31217821949aSmrg	RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels);
31227821949aSmrg    	break;
31237821949aSmrg    }
31247821949aSmrg
31257821949aSmrg    /* update cliplist */
31267821949aSmrg    if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
31277821949aSmrg    {
31287821949aSmrg	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
31297821949aSmrg	/* draw these */
31307821949aSmrg	if(pPriv->autopaint_colorkey)
31317821949aSmrg	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
31327821949aSmrg    }
31337821949aSmrg
31347821949aSmrg    /* FIXME: someone should look at these offsets, I don't think it makes sense how
31357821949aSmrg              they are handled throughout the source. */
31367821949aSmrg    RADEONDisplayVideo(pScrn, crtc, pPriv, idconv, pPriv->video_offset, offset,
31377821949aSmrg		       offset + d2line, offset + d3line, offset, offset + d2line,
31387821949aSmrg		       offset + d3line, width, height, dstPitch, xa, xb, ya,
31397821949aSmrg		       &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
31407821949aSmrg
31417821949aSmrg    pPriv->videoStatus = CLIENT_VIDEO_ON;
31427821949aSmrg
31437821949aSmrg    info->VideoTimerCallback = RADEONVideoTimerCallback;
31447821949aSmrg
31457821949aSmrg    return Success;
31467821949aSmrg}
31477821949aSmrg
31487821949aSmrg
31497821949aSmrgint
31507821949aSmrgRADEONQueryImageAttributes(
31517821949aSmrg    ScrnInfoPtr pScrn,
31527821949aSmrg    int id,
31537821949aSmrg    unsigned short *w, unsigned short *h,
31547821949aSmrg    int *pitches, int *offsets
31557821949aSmrg){
31567821949aSmrg    const RADEONInfoRec * const info = RADEONPTR(pScrn);
31577821949aSmrg    int size, tmp;
31587821949aSmrg
31597821949aSmrg    if(*w > info->xv_max_width) *w = info->xv_max_width;
31607821949aSmrg    if(*h > info->xv_max_height) *h = info->xv_max_height;
31617821949aSmrg
31627821949aSmrg    *w = RADEON_ALIGN(*w, 2);
31637821949aSmrg    if(offsets) offsets[0] = 0;
31647821949aSmrg
31657821949aSmrg    switch(id) {
31667821949aSmrg    case FOURCC_YV12:
31677821949aSmrg    case FOURCC_I420:
31687821949aSmrg	*h = RADEON_ALIGN(*h, 2);
31697821949aSmrg	size = RADEON_ALIGN(*w, 4);
31707821949aSmrg	if(pitches) pitches[0] = size;
31717821949aSmrg	size *= *h;
31727821949aSmrg	if(offsets) offsets[1] = size;
31737821949aSmrg	tmp = RADEON_ALIGN(*w >> 1, 4);
31747821949aSmrg	if(pitches) pitches[1] = pitches[2] = tmp;
31757821949aSmrg	tmp *= (*h >> 1);
31767821949aSmrg	size += tmp;
31777821949aSmrg	if(offsets) offsets[2] = size;
31787821949aSmrg	size += tmp;
31797821949aSmrg	break;
31807821949aSmrg    case FOURCC_RGBA32:
31817821949aSmrg	size = *w << 2;
31827821949aSmrg	if(pitches) pitches[0] = size;
31837821949aSmrg	size *= *h;
31847821949aSmrg	break;
31857821949aSmrg    case FOURCC_RGB24:
31867821949aSmrg	size = *w * 3;
31877821949aSmrg	if(pitches) pitches[0] = size;
31887821949aSmrg	size *= *h;
31897821949aSmrg	break;
31907821949aSmrg    case FOURCC_RGBT16:
31917821949aSmrg    case FOURCC_RGB16:
31927821949aSmrg    case FOURCC_UYVY:
31937821949aSmrg    case FOURCC_YUY2:
31947821949aSmrg    default:
31957821949aSmrg	size = *w << 1;
31967821949aSmrg	if(pitches) pitches[0] = size;
31977821949aSmrg	size *= *h;
31987821949aSmrg	break;
31997821949aSmrg    }
32007821949aSmrg
32017821949aSmrg    return size;
32027821949aSmrg}
32037821949aSmrg
32047821949aSmrgstatic void
32057821949aSmrgRADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now)
32067821949aSmrg{
32077821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
32087821949aSmrg    RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
32097821949aSmrg
32107821949aSmrg    if(pPriv->videoStatus & TIMER_MASK) {
32117821949aSmrg	if(pPriv->videoStatus & OFF_TIMER) {
32127821949aSmrg	    if(pPriv->offTime < now) {
32137821949aSmrg		unsigned char *RADEONMMIO = info->MMIO;
32147821949aSmrg		OUTREG(RADEON_OV0_SCALE_CNTL, 0);
32157821949aSmrg		pPriv->videoStatus = FREE_TIMER;
32167821949aSmrg		pPriv->freeTime = now + FREE_DELAY;
32177821949aSmrg	    }
32187821949aSmrg	} else {  /* FREE_TIMER */
32197821949aSmrg	    if(pPriv->freeTime < now) {
32207821949aSmrg		RADEONFreeVideoMemory(pScrn, pPriv);
32217821949aSmrg		pPriv->videoStatus = 0;
32227821949aSmrg		info->VideoTimerCallback = NULL;
32237821949aSmrg	    }
32247821949aSmrg	}
32257821949aSmrg    } else  /* shouldn't get here */
32267821949aSmrg	info->VideoTimerCallback = NULL;
32277821949aSmrg}
32287821949aSmrg
32297821949aSmrg/****************** Offscreen stuff ***************/
32307821949aSmrgtypedef struct {
32317821949aSmrg  void *surface_memory;
32327821949aSmrg  Bool isOn;
32337821949aSmrg} OffscreenPrivRec, * OffscreenPrivPtr;
32347821949aSmrg
32357821949aSmrgstatic int
32367821949aSmrgRADEONAllocateSurface(
32377821949aSmrg    ScrnInfoPtr pScrn,
32387821949aSmrg    int id,
32397821949aSmrg    unsigned short w,
32407821949aSmrg    unsigned short h,
32417821949aSmrg    XF86SurfacePtr surface
32427821949aSmrg){
32437821949aSmrg    int offset, pitch, size;
32447821949aSmrg    OffscreenPrivPtr pPriv;
32457821949aSmrg    void *surface_memory = NULL;
32467821949aSmrg    if((w > 1024) || (h > 1024))
32477821949aSmrg	return BadAlloc;
32487821949aSmrg
32497821949aSmrg    w = RADEON_ALIGN(w, 2);
32507821949aSmrg    pitch = RADEON_ALIGN(w << 1, 16);
32517821949aSmrg    size = pitch * h;
32527821949aSmrg
32537821949aSmrg    offset = radeon_legacy_allocate_memory(pScrn, &surface_memory, size, 64,
32547821949aSmrg		    RADEON_GEM_DOMAIN_VRAM);
32557821949aSmrg    if (offset == 0)
32567821949aSmrg	return BadAlloc;
32577821949aSmrg
32587821949aSmrg    surface->width = w;
32597821949aSmrg    surface->height = h;
32607821949aSmrg
32617821949aSmrg    if(!(surface->pitches = malloc(sizeof(int)))) {
32627821949aSmrg	radeon_legacy_free_memory(pScrn, surface_memory);
32637821949aSmrg	return BadAlloc;
32647821949aSmrg    }
32657821949aSmrg    if(!(surface->offsets = malloc(sizeof(int)))) {
32667821949aSmrg	free(surface->pitches);
32677821949aSmrg	radeon_legacy_free_memory(pScrn, surface_memory);
32687821949aSmrg	return BadAlloc;
32697821949aSmrg    }
32707821949aSmrg    if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) {
32717821949aSmrg	free(surface->pitches);
32727821949aSmrg	free(surface->offsets);
32737821949aSmrg	radeon_legacy_free_memory(pScrn, surface_memory);
32747821949aSmrg	return BadAlloc;
32757821949aSmrg    }
32767821949aSmrg
32777821949aSmrg    pPriv->surface_memory = surface_memory;
32787821949aSmrg    pPriv->isOn = FALSE;
32797821949aSmrg
32807821949aSmrg    surface->pScrn = pScrn;
32817821949aSmrg    surface->id = id;
32827821949aSmrg    surface->pitches[0] = pitch;
32837821949aSmrg    surface->offsets[0] = offset;
32847821949aSmrg    surface->devPrivate.ptr = (pointer)pPriv;
32857821949aSmrg
32867821949aSmrg    return Success;
32877821949aSmrg}
32887821949aSmrg
32897821949aSmrgstatic int
32907821949aSmrgRADEONStopSurface(
32917821949aSmrg    XF86SurfacePtr surface
32927821949aSmrg){
32937821949aSmrg  OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
32947821949aSmrg  RADEONInfoPtr info = RADEONPTR(surface->pScrn);
32957821949aSmrg  unsigned char *RADEONMMIO = info->MMIO;
32967821949aSmrg
32977821949aSmrg  if(pPriv->isOn) {
32987821949aSmrg	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
32997821949aSmrg	pPriv->isOn = FALSE;
33007821949aSmrg  }
33017821949aSmrg  return Success;
33027821949aSmrg}
33037821949aSmrg
33047821949aSmrg
33057821949aSmrgstatic int
33067821949aSmrgRADEONFreeSurface(
33077821949aSmrg    XF86SurfacePtr surface
33087821949aSmrg){
33097821949aSmrg    ScrnInfoPtr pScrn = surface->pScrn;
33107821949aSmrg    OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
33117821949aSmrg
33127821949aSmrg    if(pPriv->isOn)
33137821949aSmrg	RADEONStopSurface(surface);
33147821949aSmrg    radeon_legacy_free_memory(pScrn, pPriv->surface_memory);
33157821949aSmrg    pPriv->surface_memory = NULL;
33167821949aSmrg    free(surface->pitches);
33177821949aSmrg    free(surface->offsets);
33187821949aSmrg    free(surface->devPrivate.ptr);
33197821949aSmrg
33207821949aSmrg    return Success;
33217821949aSmrg}
33227821949aSmrg
33237821949aSmrgstatic int
33247821949aSmrgRADEONGetSurfaceAttribute(
33257821949aSmrg    ScrnInfoPtr pScrn,
33267821949aSmrg    Atom attribute,
33277821949aSmrg    INT32 *value
33287821949aSmrg){
33297821949aSmrg   return RADEONGetPortAttribute(pScrn, attribute, value,
33307821949aSmrg		(pointer)(GET_PORT_PRIVATE(pScrn)));
33317821949aSmrg}
33327821949aSmrg
33337821949aSmrgstatic int
33347821949aSmrgRADEONSetSurfaceAttribute(
33357821949aSmrg    ScrnInfoPtr pScrn,
33367821949aSmrg    Atom attribute,
33377821949aSmrg    INT32 value
33387821949aSmrg){
33397821949aSmrg   return RADEONSetPortAttribute(pScrn, attribute, value,
33407821949aSmrg		(pointer)(GET_PORT_PRIVATE(pScrn)));
33417821949aSmrg}
33427821949aSmrg
33437821949aSmrg
33447821949aSmrgstatic int
33457821949aSmrgRADEONDisplaySurface(
33467821949aSmrg    XF86SurfacePtr surface,
33477821949aSmrg    short src_x, short src_y,
33487821949aSmrg    short drw_x, short drw_y,
33497821949aSmrg    short src_w, short src_h,
33507821949aSmrg    short drw_w, short drw_h,
33517821949aSmrg    RegionPtr clipBoxes
33527821949aSmrg){
33537821949aSmrg    OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
33547821949aSmrg    ScrnInfoPtr pScrn = surface->pScrn;
33557821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
33567821949aSmrg    RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
33577821949aSmrg
33587821949aSmrg    INT32 xa, ya, xb, yb;
33597821949aSmrg    BoxRec dstBox;
33607821949aSmrg    xf86CrtcPtr crtc;
33617821949aSmrg
33627821949aSmrg    if (src_w > (drw_w << 4))
33637821949aSmrg	drw_w = src_w >> 4;
33647821949aSmrg    if (src_h > (drw_h << 4))
33657821949aSmrg	drw_h = src_h >> 4;
33667821949aSmrg
33677821949aSmrg    xa = src_x;
33687821949aSmrg    xb = src_x + src_w;
33697821949aSmrg    ya = src_y;
33707821949aSmrg    yb = src_y + src_h;
33717821949aSmrg
33727821949aSmrg    dstBox.x1 = drw_x;
33737821949aSmrg    dstBox.x2 = drw_x + drw_w;
33747821949aSmrg    dstBox.y1 = drw_y;
33757821949aSmrg    dstBox.y2 = drw_y + drw_h;
33767821949aSmrg
33777821949aSmrg    if (!radeon_crtc_clip_video(pScrn, &crtc, portPriv->desired_crtc,
33787821949aSmrg				&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
33797821949aSmrg				surface->width, surface->height))
33807821949aSmrg        return Success;
33817821949aSmrg
33827821949aSmrg   if (!crtc) {
33837821949aSmrg       if (pPriv->isOn) {
33847821949aSmrg	   unsigned char *RADEONMMIO = info->MMIO;
33857821949aSmrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
33867821949aSmrg	   pPriv->isOn = FALSE;
33877821949aSmrg       }
33887821949aSmrg       return Success;
33897821949aSmrg   }
33907821949aSmrg
33917821949aSmrg    dstBox.x1 -= crtc->x;
33927821949aSmrg    dstBox.x2 -= crtc->x;
33937821949aSmrg    dstBox.y1 -= crtc->y;
33947821949aSmrg    dstBox.y2 -= crtc->y;
33957821949aSmrg
33967821949aSmrg#if 0
33977821949aSmrg    /* this isn't needed */
33987821949aSmrg    RADEONResetVideo(pScrn);
33997821949aSmrg#endif
34007821949aSmrg    RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id,
34017821949aSmrg		       surface->offsets[0], surface->offsets[0],
34027821949aSmrg		       surface->offsets[0], surface->offsets[0],
34037821949aSmrg		       surface->offsets[0], surface->offsets[0],
34047821949aSmrg		       surface->offsets[0], surface->width, surface->height,
34057821949aSmrg		       surface->pitches[0], xa, xb, ya, &dstBox, src_w, src_h,
34067821949aSmrg		       drw_w, drw_h, METHOD_BOB);
34077821949aSmrg
34087821949aSmrg    if (portPriv->autopaint_colorkey)
34097821949aSmrg	xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
34107821949aSmrg
34117821949aSmrg    pPriv->isOn = TRUE;
34127821949aSmrg    /* we've prempted the XvImage stream so set its free timer */
34137821949aSmrg    if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
34147821949aSmrg	REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
34157821949aSmrg	UpdateCurrentTime();
34167821949aSmrg	portPriv->videoStatus = FREE_TIMER;
34177821949aSmrg	portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
34187821949aSmrg	info->VideoTimerCallback = RADEONVideoTimerCallback;
34197821949aSmrg    }
34207821949aSmrg
34217821949aSmrg    return Success;
3422de2362d3Smrg}
34237821949aSmrg
34247821949aSmrg
34257821949aSmrgstatic void
34267821949aSmrgRADEONInitOffscreenImages(ScreenPtr pScreen)
34277821949aSmrg{
34287821949aSmrg/*  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
34297821949aSmrg    RADEONInfoPtr info = RADEONPTR(pScrn); */
34307821949aSmrg    XF86OffscreenImagePtr offscreenImages;
34317821949aSmrg    /* need to free this someplace */
34327821949aSmrg
34337821949aSmrg    if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec))))
34347821949aSmrg	return;
34357821949aSmrg
34367821949aSmrg    offscreenImages[0].image = &Images[0];
34377821949aSmrg    offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*|
34387821949aSmrg			       VIDEO_CLIP_TO_VIEWPORT*/;
34397821949aSmrg    offscreenImages[0].alloc_surface = RADEONAllocateSurface;
34407821949aSmrg    offscreenImages[0].free_surface = RADEONFreeSurface;
34417821949aSmrg    offscreenImages[0].display = RADEONDisplaySurface;
34427821949aSmrg    offscreenImages[0].stop = RADEONStopSurface;
34437821949aSmrg    offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute;
34447821949aSmrg    offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute;
34457821949aSmrg    offscreenImages[0].max_width = 2047;
34467821949aSmrg    offscreenImages[0].max_height = 2047;
34477821949aSmrg    offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
34487821949aSmrg    offscreenImages[0].attributes = Attributes;
34497821949aSmrg
34507821949aSmrg    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
34517821949aSmrg}
34527821949aSmrg
34537821949aSmrg         /* TV-in functions */
34547821949aSmrg
34557821949aSmrgstatic int
34567821949aSmrgRADEONPutVideo(
34577821949aSmrg  ScrnInfoPtr pScrn,
34587821949aSmrg  short src_x, short src_y,
34597821949aSmrg  short drw_x, short drw_y,
34607821949aSmrg  short src_w, short src_h,
34617821949aSmrg  short drw_w, short drw_h,
34627821949aSmrg  RegionPtr clipBoxes, pointer data,
34637821949aSmrg  DrawablePtr pDraw
34647821949aSmrg){
34657821949aSmrg   RADEONInfoPtr info = RADEONPTR(pScrn);
34667821949aSmrg   RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
34677821949aSmrg   unsigned char *RADEONMMIO = info->MMIO;
34687821949aSmrg   INT32 xa, xb, ya, yb, top;
34697821949aSmrg   unsigned int pitch, new_size, alloc_size;
34707821949aSmrg   unsigned int offset1, offset2, offset3, offset4, s2offset, s3offset;
34717821949aSmrg   unsigned int vbi_offset0, vbi_offset1;
34727821949aSmrg   int srcPitch, srcPitch2, dstPitch;
34737821949aSmrg   int bpp;
34747821949aSmrg   BoxRec dstBox;
34757821949aSmrg   uint32_t id, display_base;
34767821949aSmrg   int width, height;
34777821949aSmrg   int mult;
34787821949aSmrg   int vbi_line_width, vbi_start, vbi_end;
34797821949aSmrg   xf86CrtcPtr crtc;
34807821949aSmrg
34817821949aSmrg    RADEON_SYNC(info, pScrn);
34827821949aSmrg   /*
34837821949aSmrg    * s2offset, s3offset - byte offsets into U and V plane of the
34847821949aSmrg    *                      source where copying starts.  Y plane is
34857821949aSmrg    *                      done by editing "buf".
34867821949aSmrg    *
34877821949aSmrg    * offset - byte offset to the first line of the destination.
34887821949aSmrg    *
34897821949aSmrg    * dst_start - byte address to the first displayed pel.
34907821949aSmrg    *
34917821949aSmrg    */
34927821949aSmrg
34937821949aSmrg   /* make the compiler happy */
34947821949aSmrg   s2offset = s3offset = srcPitch2 = 0;
34957821949aSmrg
34967821949aSmrg   if(src_w > (drw_w << 4))
34977821949aSmrg        drw_w = src_w >> 4;
34987821949aSmrg   if(src_h > (drw_h << 4))
34997821949aSmrg        drw_h = src_h >> 4;
35007821949aSmrg
35017821949aSmrg   /* Clip */
35027821949aSmrg   xa = src_x;
35037821949aSmrg   xb = src_x + src_w;
35047821949aSmrg   ya = src_y;
35057821949aSmrg   yb = src_y + src_h;
35067821949aSmrg
35077821949aSmrg   dstBox.x1 = drw_x;
35087821949aSmrg   dstBox.x2 = drw_x + drw_w;
35097821949aSmrg   dstBox.y1 = drw_y;
35107821949aSmrg   dstBox.y2 = drw_y + drw_h;
35117821949aSmrg
35127821949aSmrg   width = InputVideoEncodings[pPriv->encoding].width;
35137821949aSmrg   height = InputVideoEncodings[pPriv->encoding].height;
35147821949aSmrg
35157821949aSmrg   vbi_line_width = 798*2;
35167821949aSmrg   if(width<=640)
35177821949aSmrg       vbi_line_width = 0x640; /* 1600 actually */
35187821949aSmrg   else
35197821949aSmrg       vbi_line_width = 2000; /* might need adjustment */
35207821949aSmrg
35217821949aSmrg   if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
35227821949aSmrg			       &dstBox, &xa, &xb, &ya, &yb,
35237821949aSmrg			       clipBoxes, width, height))
35247821949aSmrg       return Success;
35257821949aSmrg
35267821949aSmrg   if (!crtc) {
35277821949aSmrg       if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
35287821949aSmrg	   unsigned char *RADEONMMIO = info->MMIO;
35297821949aSmrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
35307821949aSmrg	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
35317821949aSmrg       }
35327821949aSmrg       return Success;
35337821949aSmrg   }
35347821949aSmrg
35357821949aSmrg   dstBox.x1 -= crtc->x;
35367821949aSmrg   dstBox.x2 -= crtc->x;
35377821949aSmrg   dstBox.y1 -= crtc->y;
35387821949aSmrg   dstBox.y2 -= crtc->y;
35397821949aSmrg
35407821949aSmrg   bpp = pScrn->bitsPerPixel >> 3;
35417821949aSmrg   pitch = bpp * pScrn->displayWidth;
35427821949aSmrg
35437821949aSmrg   switch(pPriv->overlay_deinterlacing_method){
35447821949aSmrg        case METHOD_BOB:
35457821949aSmrg        case METHOD_SINGLE:
35467821949aSmrg                mult=2;
35477821949aSmrg                break;
35487821949aSmrg        case METHOD_WEAVE:
35497821949aSmrg        case METHOD_ADAPTIVE:
35507821949aSmrg                mult=4;
35517821949aSmrg                break;
35527821949aSmrg        default:
35537821949aSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n");
35547821949aSmrg                mult=4;
35557821949aSmrg        }
35567821949aSmrg
35577821949aSmrg   id = FOURCC_YUY2;
35587821949aSmrg
35597821949aSmrg   top = ya>>16;
35607821949aSmrg#if 0
35617821949aSmrg   /* setting the ID above makes this useful - needs revisiting */
35627821949aSmrg   switch(id) {
35637821949aSmrg   case FOURCC_YV12:
35647821949aSmrg   case FOURCC_I420:
35657821949aSmrg        top &= ~1;
35667821949aSmrg        dstPitch = RADEON_ALIGN(width << 1, 16);
35677821949aSmrg        srcPitch = RADEON_ALIGN(width, 4);
35687821949aSmrg        s2offset = srcPitch * height;
35697821949aSmrg        srcPitch2 = RADEON_ALIGN(width >> 1, 4);
35707821949aSmrg        s3offset = (srcPitch2 * (height >> 1)) + s2offset;
35717821949aSmrg        break;
35727821949aSmrg   case FOURCC_UYVY:
35737821949aSmrg   case FOURCC_YUY2:
35747821949aSmrg   default:
35757821949aSmrg        dstPitch = RADEON_ALIGN(width<<1, 16);
35767821949aSmrg        srcPitch = (width<<1);
35777821949aSmrg        break;
35787821949aSmrg   }
35797821949aSmrg#else
35807821949aSmrg   dstPitch = RADEON_ALIGN(width << 1, 16);
35817821949aSmrg   srcPitch = (width<<1);
35827821949aSmrg#endif
35837821949aSmrg
35847821949aSmrg   new_size = dstPitch * height;
35857821949aSmrg   new_size = new_size + 0x1f; /* for aligning */
35867821949aSmrg   alloc_size = new_size * mult;
35877821949aSmrg   if (pPriv->capture_vbi_data)
35887821949aSmrg      alloc_size += 2 * 2 * vbi_line_width * 21;
35897821949aSmrg
35907821949aSmrg   pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
35917821949aSmrg						      (pPriv->doubleBuffer ?
35927821949aSmrg						      (new_size * 2) : new_size), 64,
35937821949aSmrg						      RADEON_GEM_DOMAIN_GTT);
35947821949aSmrg   if (pPriv->video_offset == 0)
35957821949aSmrg      return BadAlloc;
35967821949aSmrg
35977821949aSmrg/* I have suspicion that capture engine must be active _before_ Rage Theatre
35987821949aSmrg   is being manipulated with.. */
35997821949aSmrg
36007821949aSmrg   RADEONWaitForIdleMMIO(pScrn);
36017821949aSmrg   display_base=INREG(RADEON_DISPLAY_BASE_ADDR);
36027821949aSmrg
36037821949aSmrg/*   RADEONWaitForFifo(pScrn, 15); */
36047821949aSmrg
36057821949aSmrg   switch(pPriv->overlay_deinterlacing_method){
36067821949aSmrg        case METHOD_BOB:
36077821949aSmrg        case METHOD_SINGLE:
36087821949aSmrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
36097821949aSmrg           offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
36107821949aSmrg           offset3 = offset1;
36117821949aSmrg           offset4 = offset2;
36127821949aSmrg           break;
36137821949aSmrg        case METHOD_WEAVE:
36147821949aSmrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
36157821949aSmrg           offset2 = offset1+dstPitch;
36167821949aSmrg           offset3 = RADEON_ALIGN(pPriv->video_offset + 2 * new_size, 0x10);
36177821949aSmrg           offset4 = offset3+dstPitch;
36187821949aSmrg           break;
36197821949aSmrg        default:
36207821949aSmrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
36217821949aSmrg           offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
36227821949aSmrg           offset3 = offset1;
36237821949aSmrg           offset4 = offset2;
36247821949aSmrg        }
36257821949aSmrg
36267821949aSmrg   OUTREG(RADEON_CAP0_BUF0_OFFSET,        offset1+display_base);
36277821949aSmrg   OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET,   offset2+display_base);
36287821949aSmrg   OUTREG(RADEON_CAP0_BUF1_OFFSET,        offset3+display_base);
36297821949aSmrg   OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET,   offset4+display_base);
36307821949aSmrg
36317821949aSmrg   OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base);
36327821949aSmrg
36337821949aSmrg   if(pPriv->capture_vbi_data){
36347821949aSmrg        if ((pPriv->encoding==2)||(pPriv->encoding==8)) {
36357821949aSmrg            /* PAL, SECAM */
36367821949aSmrg            vbi_start = 5;
36377821949aSmrg            vbi_end = 21;
36387821949aSmrg        } else {
36397821949aSmrg            /* NTSC */
36407821949aSmrg            vbi_start = 8;
36417821949aSmrg            vbi_end = 20;
36427821949aSmrg        }
36437821949aSmrg
36447821949aSmrg        vbi_offset0 = RADEON_ALIGN(pPriv->video_offset + mult * new_size * bpp, 0x10);
36457821949aSmrg        vbi_offset1 = vbi_offset0 + dstPitch*20;
36467821949aSmrg        OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base);
36477821949aSmrg        OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base);
36487821949aSmrg        OUTREG(RADEON_CAP0_VBI2_OFFSET, 0);
36497821949aSmrg        OUTREG(RADEON_CAP0_VBI3_OFFSET, 0);
36507821949aSmrg        OUTREG(RADEON_CAP0_VBI_V_WINDOW, vbi_start | (vbi_end<<16));
36517821949aSmrg        OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16);
36527821949aSmrg        }
36537821949aSmrg
36547821949aSmrg   OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2);
36557821949aSmrg   OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16);
36567821949aSmrg   OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1));
36577821949aSmrg   if(mult==2){
36587821949aSmrg           OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB);
36597821949aSmrg           } else {
36607821949aSmrg           OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE);
36617821949aSmrg           }
36627821949aSmrg   OUTREG(RADEON_CAP0_DEBUG, 0);
36637821949aSmrg
36647821949aSmrg   OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01);
36657821949aSmrg   OUTREG(RADEON_TEST_DEBUG_CNTL, 0);
36667821949aSmrg
36677821949aSmrg   if(! pPriv->video_stream_active)
36687821949aSmrg   {
36697821949aSmrg
36707821949aSmrg      RADEONWaitForIdleMMIO(pScrn);
36717821949aSmrg      OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 );
36727821949aSmrg      OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0);
36737821949aSmrg      OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK);
36747821949aSmrg      OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11);
36757821949aSmrg      if(pPriv->theatre != NULL)
36767821949aSmrg      {
36777821949aSmrg         RADEON_RT_SetEncoding(pScrn, pPriv);
36787821949aSmrg      }
36797821949aSmrg      if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
36807821949aSmrg      if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
36817821949aSmrg      if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
36827821949aSmrg      if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
36837821949aSmrg   }
36847821949aSmrg
36857821949aSmrg
36867821949aSmrg   /* update cliplist */
36877821949aSmrg   if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
36887821949aSmrg        REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
36897821949aSmrg        /* draw these */
36907821949aSmrg        if(pPriv->autopaint_colorkey)
36917821949aSmrg	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
36927821949aSmrg   }
36937821949aSmrg
36947821949aSmrg   RADEONDisplayVideo(pScrn, crtc, pPriv, id, pPriv->video_offset,
36957821949aSmrg		      offset1+top*srcPitch, offset2+top*srcPitch,
36967821949aSmrg		      offset3+top*srcPitch, offset4+top*srcPitch,
36977821949aSmrg		      offset1+top*srcPitch, offset2+top*srcPitch, width, height,
36987821949aSmrg		      dstPitch*mult/2, xa, xb, ya, &dstBox, src_w, src_h*mult/2,
36997821949aSmrg		      drw_w, drw_h, pPriv->overlay_deinterlacing_method);
37007821949aSmrg
37017821949aSmrg   RADEONWaitForFifo(pScrn, 1);
37027821949aSmrg   OUTREG(RADEON_OV0_REG_LOAD_CNTL,  RADEON_REG_LD_CTL_LOCK);
37037821949aSmrg   RADEONWaitForIdleMMIO(pScrn);
37047821949aSmrg   while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
37057821949aSmrg
37067821949aSmrg
37077821949aSmrg   switch(pPriv->overlay_deinterlacing_method){
37087821949aSmrg        case METHOD_BOB:
37097821949aSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
37107821949aSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/
37117821949aSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
37127821949aSmrg           break;
37137821949aSmrg        case METHOD_SINGLE:
37147821949aSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
37157821949aSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
37167821949aSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
37177821949aSmrg           break;
37187821949aSmrg        case METHOD_WEAVE:
37197821949aSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28));
37207821949aSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0  |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
37217821949aSmrg                | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN
37227821949aSmrg                /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */
37237821949aSmrg                /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */
37247821949aSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE);
37257821949aSmrg           break;
37267821949aSmrg        default:
37277821949aSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
37287821949aSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
37297821949aSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
37307821949aSmrg        }
37317821949aSmrg
37327821949aSmrg
37337821949aSmrg   RADEONWaitForIdleMMIO(pScrn);
37347821949aSmrg   OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
37357821949aSmrg   OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
37367821949aSmrg
37377821949aSmrg   OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
37387821949aSmrg
37397821949aSmrg#if 0
37407821949aSmrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL));
37417821949aSmrg/*   OUTREG(RADEON_OV0_FLAG_CNTL, 8); */
37427821949aSmrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL));
37437821949aSmrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS));
37447821949aSmrg
37457821949aSmrg/*   OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */
37467821949aSmrg#endif
37477821949aSmrg
37487821949aSmrg   pPriv->videoStatus = CLIENT_VIDEO_ON;
37497821949aSmrg   pPriv->video_stream_active = TRUE;
37507821949aSmrg
37517821949aSmrg   info->VideoTimerCallback = RADEONVideoTimerCallback;
37527821949aSmrg
37537821949aSmrg   return Success;
37547821949aSmrg}
37557821949aSmrg        /* miscellaneous TV-in helper functions */
37567821949aSmrg
37577821949aSmrgstatic void RADEON_board_setmisc(RADEONPortPrivPtr pPriv)
37587821949aSmrg{
37597821949aSmrg    /* Adjust PAL/SECAM constants for FI1216MF tuner */
37607821949aSmrg    if((((pPriv->tuner_type & 0xf)==5) ||
37617821949aSmrg        ((pPriv->tuner_type & 0xf)==11)||
37627821949aSmrg        ((pPriv->tuner_type & 0xf)==14))
37637821949aSmrg        && (pPriv->fi1236!=NULL))
37647821949aSmrg    {
37657821949aSmrg        if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/
37667821949aSmrg        {
37677821949aSmrg           pPriv->fi1236->parm.band_low = 0xA1;
37687821949aSmrg           pPriv->fi1236->parm.band_mid = 0x91;
37697821949aSmrg           pPriv->fi1236->parm.band_high = 0x31;
37707821949aSmrg        }
37717821949aSmrg        if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/
37727821949aSmrg        {
37737821949aSmrg           pPriv->fi1236->parm.band_low = 0xA3;
37747821949aSmrg           pPriv->fi1236->parm.band_mid = 0x93;
37757821949aSmrg           pPriv->fi1236->parm.band_high = 0x33;
37767821949aSmrg        }
37777821949aSmrg    }
37787821949aSmrg
37797821949aSmrg}
37807821949aSmrg
37817821949aSmrgstatic void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
37827821949aSmrg{
37837821949aSmrgint width, height;
37847821949aSmrgRADEONWaitForIdleMMIO(pScrn);
37857821949aSmrg
37867821949aSmrg/* Disable VBI capture for anything but TV tuner */
37877821949aSmrgswitch(pPriv->encoding){
37887821949aSmrg	case 2:
37897821949aSmrg	case 5:
37907821949aSmrg	case 8:
37917821949aSmrg		pPriv->capture_vbi_data=1;
37927821949aSmrg		break;
37937821949aSmrg	default:
37947821949aSmrg		pPriv->capture_vbi_data=0;
37957821949aSmrg	}
37967821949aSmrg
37977821949aSmrgswitch(pPriv->encoding){
37987821949aSmrg        case 1:
37997821949aSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
38007821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
38017821949aSmrg                pPriv->v=25;
38027821949aSmrg                break;
38037821949aSmrg        case 2:
38047821949aSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
38057821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
38067821949aSmrg                pPriv->v=25;
38077821949aSmrg                break;
38087821949aSmrg        case 3:
38097821949aSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
38107821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
38117821949aSmrg                pPriv->v=25;
38127821949aSmrg                break;
38137821949aSmrg        case 4:
38147821949aSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE,0);
38157821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
38167821949aSmrg                pPriv->v=23;
38177821949aSmrg                break;
38187821949aSmrg        case 5:
38197821949aSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
38207821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
38217821949aSmrg                pPriv->v=23;
38227821949aSmrg                break;
38237821949aSmrg        case 6:
38247821949aSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
38257821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
38267821949aSmrg                pPriv->v=23;
38277821949aSmrg                break;
38287821949aSmrg        case 7:
38297821949aSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE, 0);
38307821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
38317821949aSmrg                pPriv->v=25;
38327821949aSmrg                break;
38337821949aSmrg        case 8:
38347821949aSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
38357821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
38367821949aSmrg                pPriv->v=25;
38377821949aSmrg                break;
38387821949aSmrg        case 9:
38397821949aSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
38407821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
38417821949aSmrg                pPriv->v=25;
38427821949aSmrg                break;
38437821949aSmrg        case 10:
38447821949aSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
38457821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
38467821949aSmrg                pPriv->v=25;
38477821949aSmrg                break;
38487821949aSmrg        case 11:
38497821949aSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
38507821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
38517821949aSmrg                pPriv->v=25;
38527821949aSmrg                break;
38537821949aSmrg        case 12:
38547821949aSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
38557821949aSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
38567821949aSmrg                pPriv->v=25;
38577821949aSmrg                break;
38587821949aSmrg        default:
38597821949aSmrg                pPriv->v=0;
38607821949aSmrg                return;
38617821949aSmrg        }
38627821949aSmrgxf86_RT_SetInterlace(pPriv->theatre, 1);
38637821949aSmrgwidth = InputVideoEncodings[pPriv->encoding].width;
38647821949aSmrgheight = InputVideoEncodings[pPriv->encoding].height;
38657821949aSmrgxf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data);
38667821949aSmrg}
38677821949aSmrg
38687821949aSmrgstatic void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv)
38697821949aSmrg{
38707821949aSmrgxf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
38717821949aSmrgswitch(pPriv->encoding){
38727821949aSmrg        case 1:
38737821949aSmrg                pPriv->msp3430->standard = MSP3430_PAL;
38747821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
38757821949aSmrg                break;
38767821949aSmrg        case 2:
38777821949aSmrg                pPriv->msp3430->standard = MSP3430_PAL;
38787821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
38797821949aSmrg                break;
38807821949aSmrg        case 3:
38817821949aSmrg                pPriv->msp3430->standard = MSP3430_PAL;
38827821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
38837821949aSmrg                break;
38847821949aSmrg        case 4:
38857821949aSmrg                pPriv->msp3430->standard = MSP3430_NTSC;
38867821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
38877821949aSmrg                break;
38887821949aSmrg        case 5:
38897821949aSmrg                pPriv->msp3430->standard = MSP3430_NTSC;
38907821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
38917821949aSmrg                break;
38927821949aSmrg        case 6:
38937821949aSmrg                pPriv->msp3430->standard = MSP3430_NTSC;
38947821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
38957821949aSmrg                break;
38967821949aSmrg        case 7:
38977821949aSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
38987821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
38997821949aSmrg                break;
39007821949aSmrg        case 8:
39017821949aSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
39027821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
39037821949aSmrg                break;
39047821949aSmrg        case 9:
39057821949aSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
39067821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
39077821949aSmrg                break;
39087821949aSmrg        case 10:
39097821949aSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
39107821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
39117821949aSmrg                break;
39127821949aSmrg        case 11:
39137821949aSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
39147821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
39157821949aSmrg                break;
39167821949aSmrg        case 12:
39177821949aSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
39187821949aSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
39197821949aSmrg                break;
39207821949aSmrg        default:
39217821949aSmrg                return;
39227821949aSmrg        }
39237821949aSmrgxf86_InitMSP3430(pPriv->msp3430);
39247821949aSmrgxf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
39257821949aSmrg}
39267821949aSmrg
39277821949aSmrgstatic void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv)
39287821949aSmrg{
39297821949aSmrgTDA9885Ptr t=pPriv->tda9885;
39307821949aSmrg
39317821949aSmrgswitch(pPriv->encoding){
39327821949aSmrg                /* PAL */
39337821949aSmrg        case 1:
39347821949aSmrg        case 2:
39357821949aSmrg        case 3:
39367821949aSmrg                t->standard_video_if=2;
39377821949aSmrg                t->standard_sound_carrier=1;
39387821949aSmrg					 t->modulation=2; /* negative FM */
39397821949aSmrg                break;
39407821949aSmrg                /* NTSC */
39417821949aSmrg        case 4:
39427821949aSmrg        case 5:
39437821949aSmrg        case 6:
39447821949aSmrg                t->standard_video_if=1;
39457821949aSmrg                t->standard_sound_carrier=0;
39467821949aSmrg					 t->modulation=2; /* negative FM */
39477821949aSmrg                break;
39487821949aSmrg                /* SECAM */
39497821949aSmrg        case 7:
39507821949aSmrg        case 8:
39517821949aSmrg        case 9:
39527821949aSmrg        case 10:
39537821949aSmrg        case 11:
39547821949aSmrg        case 12:
39557821949aSmrg                t->standard_video_if=0;
39567821949aSmrg                t->standard_sound_carrier=3;
39577821949aSmrg                t->modulation=0; /* positive AM */
39587821949aSmrg                break;
39597821949aSmrg        default:
39607821949aSmrg                return;
39617821949aSmrg        }
39627821949aSmrgxf86_tda9885_setparameters(pPriv->tda9885);
39637821949aSmrgxf86_tda9885_getstatus(pPriv->tda9885);
39647821949aSmrgxf86_tda9885_dumpstatus(pPriv->tda9885);
39657821949aSmrg}
39667821949aSmrg
39677821949aSmrgstatic void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv)
39687821949aSmrg{
39697821949aSmrg/* at the moment this only affect MT2032 */
39707821949aSmrgswitch(pPriv->encoding){
39717821949aSmrg                /* PAL */
39727821949aSmrg        case 1:
39737821949aSmrg        case 2:
39747821949aSmrg        case 3:
39757821949aSmrg		pPriv->fi1236->video_if=38.900;
39767821949aSmrg                break;
39777821949aSmrg                /* NTSC */
39787821949aSmrg        case 4:
39797821949aSmrg        case 5:
39807821949aSmrg        case 6:
39817821949aSmrg		pPriv->fi1236->video_if=45.7812;
39827821949aSmrg		pPriv->fi1236->video_if=45.750;
39837821949aSmrg		pPriv->fi1236->video_if=45.125;
39847821949aSmrg                break;
39857821949aSmrg                /* SECAM */
39867821949aSmrg        case 7:
39877821949aSmrg        case 8:
39887821949aSmrg        case 9:
39897821949aSmrg        case 10:
39907821949aSmrg        case 11:
39917821949aSmrg        case 12:
39927821949aSmrg		pPriv->fi1236->video_if=58.7812;
39937821949aSmrg                break;
39947821949aSmrg        default:
39957821949aSmrg                return;
39967821949aSmrg        }
39977821949aSmrg}
39987821949aSmrg
3999