1209ff23fSmrg
2209ff23fSmrg#ifdef HAVE_CONFIG_H
3209ff23fSmrg#include "config.h"
4209ff23fSmrg#endif
5209ff23fSmrg
6209ff23fSmrg#include <stdlib.h>
7209ff23fSmrg#include <string.h>
8209ff23fSmrg#include <stdio.h>
9209ff23fSmrg#include <math.h>
10209ff23fSmrg
11209ff23fSmrg#include "radeon.h"
12209ff23fSmrg#include "radeon_reg.h"
1343df4709Smrg#include "radeon_macros.h"
14209ff23fSmrg#include "radeon_probe.h"
15209ff23fSmrg#include "radeon_video.h"
16209ff23fSmrg
17209ff23fSmrg#include "xf86.h"
18209ff23fSmrg#include "dixstruct.h"
1943df4709Smrg#include "atipciids.h"
2043df4709Smrg#include "xf86fbman.h"
21209ff23fSmrg
2268105dcbSveego/* DPMS */
2368105dcbSveego#ifdef HAVE_XEXTPROTO_71
2468105dcbSveego#include <X11/extensions/dpmsconst.h>
2568105dcbSveego#else
2668105dcbSveego#define DPMS_SERVER
2768105dcbSveego#include <X11/extensions/dpms.h>
2868105dcbSveego#endif
2968105dcbSveego
30209ff23fSmrg#include <X11/extensions/Xv.h>
31209ff23fSmrg#include "fourcc.h"
32209ff23fSmrg
3343df4709Smrg#include "theatre_detect.h"
3443df4709Smrg#include "theatre_reg.h"
3543df4709Smrg#include "fi1236.h"
3643df4709Smrg#include "msp3430.h"
3743df4709Smrg#include "tda9885.h"
3843df4709Smrg
39209ff23fSmrg#define OFF_DELAY       250  /* milliseconds */
40209ff23fSmrg#define FREE_DELAY      15000
41209ff23fSmrg
42209ff23fSmrg#define OFF_TIMER       0x01
43209ff23fSmrg#define FREE_TIMER      0x02
44209ff23fSmrg#define CLIENT_VIDEO_ON 0x04
45209ff23fSmrg
4643df4709Smrg#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
4743df4709Smrg
4843df4709Smrg/* capture config constants */
4943df4709Smrg#define BUF_TYPE_FIELD          0
5043df4709Smrg#define BUF_TYPE_ALTERNATING    1
5143df4709Smrg#define BUF_TYPE_FRAME          2
5243df4709Smrg
5343df4709Smrg
5443df4709Smrg#define BUF_MODE_SINGLE         0
5543df4709Smrg#define BUF_MODE_DOUBLE         1
5643df4709Smrg#define BUF_MODE_TRIPLE         2
5743df4709Smrg/* CAP0_CONFIG values */
5843df4709Smrg
5943df4709Smrg#define FORMAT_BROOKTREE        0
6043df4709Smrg#define FORMAT_CCIR656          1
6143df4709Smrg#define FORMAT_ZV               2
6243df4709Smrg#define FORMAT_VIP16            3
6343df4709Smrg#define FORMAT_TRANSPORT        4
6443df4709Smrg
6543df4709Smrg#define ENABLE_RADEON_CAPTURE_WEAVE (RADEON_CAP0_CONFIG_CONTINUOS \
6643df4709Smrg                        | (BUF_MODE_DOUBLE <<7) \
6743df4709Smrg                        | (BUF_TYPE_FRAME << 4) \
6843df4709Smrg                        | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
6943df4709Smrg                        | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
7043df4709Smrg                        | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
7143df4709Smrg                        | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
7243df4709Smrg
7343df4709Smrg#define ENABLE_RADEON_CAPTURE_BOB (RADEON_CAP0_CONFIG_CONTINUOS \
7443df4709Smrg                        | (BUF_MODE_SINGLE <<7)  \
7543df4709Smrg                        | (BUF_TYPE_ALTERNATING << 4) \
7643df4709Smrg                        | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
7743df4709Smrg                        | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
7843df4709Smrg                        | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
7943df4709Smrg                        | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
8043df4709Smrg
8143df4709Smrg
8243df4709Smrgstatic void RADEONInitOffscreenImages(ScreenPtr);
8343df4709Smrg
8443df4709Smrgstatic XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr);
8543df4709Smrgstatic int  RADEONPutImage(ScrnInfoPtr, short, short, short, short, short,
8643df4709Smrg			short, short, short, int, unsigned char*, short,
8743df4709Smrg			short, Bool, RegionPtr, pointer,
8843df4709Smrg			DrawablePtr);
8943df4709Smrgstatic void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
9043df4709Smrgstatic int RADEONPutVideo(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y,
9143df4709Smrg                        short src_w, short src_h, short drw_w, short drw_h,
9243df4709Smrg			RegionPtr clipBoxes, pointer data, DrawablePtr pDraw);
9343df4709Smrg
9443df4709Smrgstatic void RADEON_board_setmisc(RADEONPortPrivPtr pPriv);
9543df4709Smrgstatic void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
9643df4709Smrgstatic void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv);
9743df4709Smrgstatic void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv);
9843df4709Smrgstatic void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv);
9943df4709Smrg
10043df4709Smrgstatic Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
10143df4709Smrgstatic Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
10243df4709Smrgstatic Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
10343df4709Smrgstatic Atom xvGamma, xvColorspace;
10443df4709Smrgstatic Atom xvCRTC;
10543df4709Smrgstatic Atom xvEncoding, xvFrequency, xvVolume, xvMute,
10643df4709Smrg	     xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
10743df4709Smrg	     xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
10843df4709Smrg	     xvLocationID, xvDeviceID, xvInstanceID, xvDumpStatus,
10943df4709Smrg	     xvAdjustment;
11043df4709Smrg
11143df4709Smrgstatic Atom xvOvAlpha, xvGrAlpha, xvAlphaMode;
11243df4709Smrg
113209ff23fSmrg#define GET_PORT_PRIVATE(pScrn) \
114209ff23fSmrg   (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
115209ff23fSmrg
116209ff23fSmrgstatic void
117209ff23fSmrgradeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
118209ff23fSmrg{
119209ff23fSmrg    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
120209ff23fSmrg    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
121209ff23fSmrg    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
122209ff23fSmrg    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
123209ff23fSmrg
124209ff23fSmrg    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
125209ff23fSmrg	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
126209ff23fSmrg}
127209ff23fSmrg
128209ff23fSmrgstatic void
129209ff23fSmrgradeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
130209ff23fSmrg{
131209ff23fSmrg    if (crtc->enabled) {
132209ff23fSmrg	crtc_box->x1 = crtc->x;
133209ff23fSmrg	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
134209ff23fSmrg	crtc_box->y1 = crtc->y;
135209ff23fSmrg	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
136209ff23fSmrg    } else
137209ff23fSmrg	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
138209ff23fSmrg}
139209ff23fSmrg
140209ff23fSmrgstatic int
141209ff23fSmrgradeon_box_area(BoxPtr box)
142209ff23fSmrg{
143209ff23fSmrg    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
144209ff23fSmrg}
145209ff23fSmrg
14643df4709Smrgstatic Bool
14743df4709Smrgradeon_crtc_is_enabled(xf86CrtcPtr crtc)
14868105dcbSveego{
14943df4709Smrg    RADEONCrtcPrivatePtr radeon_crtc;
15043df4709Smrg
15143df4709Smrg#ifdef XF86DRM_MODE
15243df4709Smrg    if (RADEONPTR(crtc->scrn)->cs) {
15343df4709Smrg	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
15443df4709Smrg	return drmmode_crtc->dpms_mode == DPMSModeOn;
15543df4709Smrg    }
15643df4709Smrg#endif
15743df4709Smrg
15843df4709Smrg    radeon_crtc = crtc->driver_private;
15943df4709Smrg    return radeon_crtc->enabled;
16068105dcbSveego}
16168105dcbSveego
162b7e1c893Smrgxf86CrtcPtr
16343df4709Smrgradeon_pick_best_crtc(ScrnInfoPtr pScrn,
164ad43ddacSmrg		      int x1, int x2, int y1, int y2)
165b7e1c893Smrg{
166b7e1c893Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
16743df4709Smrg    int			coverage, best_coverage, c;
168b7e1c893Smrg    BoxRec		box, crtc_box, cover_box;
16940732134Srjs    RROutputPtr         primary_output = NULL;
17040732134Srjs    xf86CrtcPtr         best_crtc = NULL, primary_crtc = NULL;
171b7e1c893Smrg
17268105dcbSveego    if (!pScrn->vtSema)
17368105dcbSveego	return NULL;
17468105dcbSveego
175b7e1c893Smrg    box.x1 = x1;
176b7e1c893Smrg    box.x2 = x2;
177b7e1c893Smrg    box.y1 = y1;
178b7e1c893Smrg    box.y2 = y2;
179b7e1c893Smrg    best_coverage = 0;
18040732134Srjs
18140732134Srjs    /* Prefer the CRTC of the primary output */
18243df4709Smrg#ifdef HAS_DIXREGISTERPRIVATEKEY
18368105dcbSveego    if (dixPrivateKeyRegistered(rrPrivKey))
18443df4709Smrg#endif
18568105dcbSveego    {
18640732134Srjs	primary_output = RRFirstOutput(pScrn->pScreen);
18740732134Srjs    }
18840732134Srjs    if (primary_output && primary_output->crtc)
18940732134Srjs	primary_crtc = primary_output->crtc->devPrivate;
19040732134Srjs
19143df4709Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
19243df4709Smrg	xf86CrtcPtr crtc = xf86_config->crtc[c];
19343df4709Smrg
19443df4709Smrg	if (!radeon_crtc_is_enabled(crtc))
19543df4709Smrg	    continue;
19643df4709Smrg
19743df4709Smrg	radeon_crtc_box(crtc, &crtc_box);
19843df4709Smrg	radeon_box_intersect(&cover_box, &crtc_box, &box);
19943df4709Smrg	coverage = radeon_box_area(&cover_box);
20043df4709Smrg	if (coverage > best_coverage ||
20143df4709Smrg	    (coverage == best_coverage && crtc == primary_crtc)) {
20243df4709Smrg	    best_crtc = crtc;
20343df4709Smrg	    best_coverage = coverage;
204209ff23fSmrg	}
205209ff23fSmrg    }
20643df4709Smrg    return best_crtc;
20743df4709Smrg}
20843df4709Smrg
20943df4709Smrg#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
21043df4709Smrgstatic xf86CrtcPtr
21143df4709Smrgradeon_covering_crtc(ScrnInfoPtr pScrn,
21243df4709Smrg		     BoxPtr	box,
21343df4709Smrg		     xf86CrtcPtr desired,
21443df4709Smrg		     BoxPtr	crtc_box_ret)
21543df4709Smrg{
21643df4709Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
21743df4709Smrg    xf86CrtcPtr		crtc, best_crtc;
21843df4709Smrg    int			coverage, best_coverage;
21943df4709Smrg    int			c;
22043df4709Smrg    BoxRec		crtc_box, cover_box;
221209ff23fSmrg
22243df4709Smrg    best_crtc = NULL;
22343df4709Smrg    best_coverage = 0;
22443df4709Smrg    crtc_box_ret->x1 = 0;
22543df4709Smrg    crtc_box_ret->x2 = 0;
22643df4709Smrg    crtc_box_ret->y1 = 0;
22743df4709Smrg    crtc_box_ret->y2 = 0;
22843df4709Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
22943df4709Smrg	crtc = xf86_config->crtc[c];
23043df4709Smrg	radeon_crtc_box(crtc, &crtc_box);
23143df4709Smrg	radeon_box_intersect(&cover_box, &crtc_box, box);
23243df4709Smrg	coverage = radeon_box_area(&cover_box);
23343df4709Smrg	if (coverage && crtc == desired) {
23443df4709Smrg	    *crtc_box_ret = crtc_box;
23543df4709Smrg	    return crtc;
23643df4709Smrg	} else if (coverage > best_coverage) {
23743df4709Smrg	    *crtc_box_ret = crtc_box;
23843df4709Smrg	    best_crtc = crtc;
23943df4709Smrg	    best_coverage = coverage;
24043df4709Smrg	}
24143df4709Smrg    }
2426322c902Smrg    return best_crtc;
243209ff23fSmrg}
244209ff23fSmrg
24543df4709Smrgstatic Bool
24643df4709Smrgradeon_crtc_clip_video_helper(ScrnInfoPtr pScrn,
24743df4709Smrg			      xf86CrtcPtr *crtc_ret,
24843df4709Smrg			      xf86CrtcPtr desired_crtc,
24943df4709Smrg			      BoxPtr      dst,
25043df4709Smrg			      INT32	  *xa,
25143df4709Smrg			      INT32	  *xb,
25243df4709Smrg			      INT32	  *ya,
25343df4709Smrg			      INT32	  *yb,
25443df4709Smrg			      RegionPtr   reg,
25543df4709Smrg			      INT32	  width,
25643df4709Smrg			      INT32	  height)
25743df4709Smrg{
25843df4709Smrg    Bool	ret;
25943df4709Smrg    RegionRec	crtc_region_local;
26043df4709Smrg    RegionPtr	crtc_region = reg;
26143df4709Smrg
26243df4709Smrg    /*
26343df4709Smrg     * For overlay video, compute the relevant CRTC and
26443df4709Smrg     * clip video to that
26543df4709Smrg     */
26643df4709Smrg    if (crtc_ret) {
26743df4709Smrg	BoxRec		crtc_box;
26843df4709Smrg	xf86CrtcPtr	crtc = radeon_covering_crtc(pScrn, dst,
26943df4709Smrg						    desired_crtc,
27043df4709Smrg						    &crtc_box);
27143df4709Smrg
27243df4709Smrg	if (crtc) {
27343df4709Smrg	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
27443df4709Smrg	    crtc_region = &crtc_region_local;
27543df4709Smrg	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
27643df4709Smrg	}
27743df4709Smrg	*crtc_ret = crtc;
27843df4709Smrg    }
27943df4709Smrg
28043df4709Smrg    ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb,
28143df4709Smrg				crtc_region, width, height);
28243df4709Smrg
28343df4709Smrg    if (crtc_region != reg)
28443df4709Smrg	REGION_UNINIT (pScreen, &crtc_region_local);
28543df4709Smrg
28643df4709Smrg    return ret;
28743df4709Smrg}
28843df4709Smrg#endif
28943df4709Smrg
29043df4709Smrgstatic Bool
29143df4709Smrgradeon_crtc_clip_video(ScrnInfoPtr pScrn,
29243df4709Smrg		       xf86CrtcPtr *crtc_ret,
29343df4709Smrg		       xf86CrtcPtr desired_crtc,
29443df4709Smrg		       BoxPtr      dst,
29543df4709Smrg		       INT32       *xa,
29643df4709Smrg		       INT32       *xb,
29743df4709Smrg		       INT32       *ya,
29843df4709Smrg		       INT32       *yb,
29943df4709Smrg		       RegionPtr   reg,
30043df4709Smrg		       INT32       width,
30143df4709Smrg		       INT32       height)
30243df4709Smrg{
30343df4709Smrg#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
30443df4709Smrg    return radeon_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
30543df4709Smrg				       dst, xa, xb, ya, yb,
30643df4709Smrg				       reg, width, height);
30743df4709Smrg#else
30843df4709Smrg    return xf86_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
30943df4709Smrg				       dst, xa, xb, ya, yb,
31043df4709Smrg				       reg, width, height);
31143df4709Smrg#endif
31243df4709Smrg}
313209ff23fSmrg
314209ff23fSmrgvoid RADEONInitVideo(ScreenPtr pScreen)
315209ff23fSmrg{
31668105dcbSveego    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
317209ff23fSmrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
3182f39173dSmrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
319209ff23fSmrg    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
32043df4709Smrg    XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
321209ff23fSmrg    int num_adaptors;
322209ff23fSmrg
3232f39173dSmrg    /* no overlay or 3D on RN50 */
3242f39173dSmrg    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2)
3252f39173dSmrg	    return;
326209ff23fSmrg
327209ff23fSmrg    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
32843df4709Smrg    newAdaptors = malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
329209ff23fSmrg    if (newAdaptors == NULL)
330209ff23fSmrg	return;
331209ff23fSmrg
332209ff23fSmrg    memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
333209ff23fSmrg    adaptors = newAdaptors;
334209ff23fSmrg
33543df4709Smrg    if (!IS_AVIVO_VARIANT && !info->kms_enabled) {
33643df4709Smrg	overlayAdaptor = RADEONSetupImageVideo(pScreen);
33743df4709Smrg	if (overlayAdaptor != NULL) {
33843df4709Smrg	    adaptors[num_adaptors++] = overlayAdaptor;
33943df4709Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
340209ff23fSmrg	} else
34143df4709Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up overlay video\n");
34243df4709Smrg	RADEONInitOffscreenImages(pScreen);
34343df4709Smrg    }
34443df4709Smrg
34543df4709Smrg    if ((info->ChipFamily < CHIP_FAMILY_RS400)
34643df4709Smrg#ifdef XF86DRI
347b7e1c893Smrg	|| (info->directRenderingEnabled)
34843df4709Smrg#endif
349b7e1c893Smrg	) {
350b7e1c893Smrg	texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen);
351b7e1c893Smrg	if (texturedAdaptor != NULL) {
352b7e1c893Smrg	    adaptors[num_adaptors++] = texturedAdaptor;
353b7e1c893Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
354209ff23fSmrg	} else
355b7e1c893Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up textured video\n");
356209ff23fSmrg    } else
357b7e1c893Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video requires CP on R5xx/R6xx/R7xx/IGP\n");
358209ff23fSmrg
359209ff23fSmrg    if(num_adaptors)
360209ff23fSmrg	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
361209ff23fSmrg
36240732134Srjs    if(texturedAdaptor) {
36343df4709Smrg	XF86MCAdaptorPtr xvmcAdaptor = RADEONCreateAdaptorXvMC(pScreen, texturedAdaptor->name);
36440732134Srjs	if(xvmcAdaptor) {
36540732134Srjs	    if(!xf86XvMCScreenInit(pScreen, 1, &xvmcAdaptor))
36640732134Srjs		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] Failed to initialize extension.\n");
36740732134Srjs	    else
36840732134Srjs		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Extension initialized.\n");
36940732134Srjs	}
37040732134Srjs    }
37140732134Srjs
372209ff23fSmrg    if(newAdaptors)
3732f39173dSmrg	free(newAdaptors);
374209ff23fSmrg
375209ff23fSmrg}
376209ff23fSmrg
37743df4709Smrg/* client libraries expect an encoding */
37843df4709Smrgstatic XF86VideoEncodingRec DummyEncoding =
37943df4709Smrg{
38043df4709Smrg   0,
38143df4709Smrg   "XV_IMAGE",
38243df4709Smrg   2047, 2047,
38343df4709Smrg   {1, 1}
38443df4709Smrg};
385209ff23fSmrg
38643df4709Smrg /* the picture is interlaced - hence the half-heights */
38743df4709Smrg
38843df4709Smrgstatic XF86VideoEncodingRec
38943df4709SmrgInputVideoEncodings[] =
39043df4709Smrg{
39143df4709Smrg    { 0, "XV_IMAGE",			2047,2047,{1,1}},
39243df4709Smrg    { 1, "pal-composite",		720, 288, { 1, 50 }},
39343df4709Smrg    { 2, "pal-tuner",			720, 288, { 1, 50 }},
39443df4709Smrg    { 3, "pal-svideo",			720, 288, { 1, 50 }},
39543df4709Smrg    { 4, "ntsc-composite",		640, 240, { 1001, 60000 }},
39643df4709Smrg    { 5, "ntsc-tuner",			640, 240, { 1001, 60000 }},
39743df4709Smrg    { 6, "ntsc-svideo",			640, 240, { 1001, 60000 }},
39843df4709Smrg    { 7, "secam-composite",		720, 288, { 1, 50 }},
39943df4709Smrg    { 8, "secam-tuner",			720, 288, { 1, 50 }},
40043df4709Smrg    { 9, "secam-svideo",		720, 288, { 1, 50 }},
40143df4709Smrg    { 10,"pal_60-composite",		768, 288, { 1, 50 }},
40243df4709Smrg    { 11,"pal_60-tuner",		768, 288, { 1, 50 }},
40343df4709Smrg    { 12,"pal_60-svideo",		768, 288, { 1, 50 }}
40443df4709Smrg};
40543df4709Smrg
40643df4709Smrg
40743df4709Smrg#define NUM_FORMATS 12
40843df4709Smrg
40943df4709Smrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] =
41043df4709Smrg{
41143df4709Smrg   {8, TrueColor}, {8, DirectColor}, {8, PseudoColor},
41243df4709Smrg   {8, GrayScale}, {8, StaticGray}, {8, StaticColor},
41343df4709Smrg   {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
41443df4709Smrg   {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
41543df4709Smrg};
41643df4709Smrg
41743df4709Smrg
41843df4709Smrg#if 0
41943df4709Smrg#define NUM_ATTRIBUTES 9+6
42043df4709Smrg
42143df4709Smrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
42243df4709Smrg{
42343df4709Smrg   {XvSettable             ,     0,    1, "XV_SET_DEFAULTS"},
42443df4709Smrg   {XvSettable | XvGettable,     0,    1, "XV_AUTOPAINT_COLORKEY"},
42543df4709Smrg   {XvSettable | XvGettable,     0,   ~0, "XV_COLORKEY"},
42643df4709Smrg   {XvSettable | XvGettable,     0,    1, "XV_DOUBLE_BUFFER"},
42743df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
42843df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
42943df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
43043df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
43143df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
43243df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
43343df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
43443df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
43543df4709Smrg   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
43643df4709Smrg   {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
43743df4709Smrg   {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
43843df4709Smrg};
43943df4709Smrg
44043df4709Smrg#endif
44143df4709Smrg
44243df4709Smrg#define NUM_ATTRIBUTES 22
44343df4709Smrg#define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12)
44443df4709Smrg
44543df4709Smrgstatic XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] =
44643df4709Smrg{
44743df4709Smrg   {             XvGettable, 0, ~0, "XV_DEVICE_ID"},
44843df4709Smrg   {             XvGettable, 0, ~0, "XV_LOCATION_ID"},
44943df4709Smrg   {             XvGettable, 0, ~0, "XV_INSTANCE_ID"},
45043df4709Smrg   {XvSettable		   , 0, 1, "XV_DUMP_STATUS"},
45143df4709Smrg   {XvSettable             , 0, 1, "XV_SET_DEFAULTS"},
45243df4709Smrg   {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
45343df4709Smrg   {XvSettable | XvGettable, 0, ~0,"XV_COLORKEY"},
45443df4709Smrg   {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
45543df4709Smrg   {XvSettable | XvGettable,     0,  255, "XV_OVERLAY_ALPHA"},
45643df4709Smrg   {XvSettable | XvGettable,     0,  255, "XV_GRAPHICS_ALPHA"},
45743df4709Smrg   {XvSettable | XvGettable,     0,    1, "XV_ALPHA_MODE"},
45843df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
45943df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
46043df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
46143df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
46243df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
46343df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
46443df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
46543df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
46643df4709Smrg   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
46743df4709Smrg   {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
46843df4709Smrg   {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
46943df4709Smrg
47043df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_BRIGHTNESS"},
47143df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_CONTRAST"},
47243df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_SATURATION"},
47343df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_HUE"},
47443df4709Smrg   {XvSettable | XvGettable, 0, 2, "XV_OVERLAY_DEINTERLACING_METHOD"},
47543df4709Smrg   {XvSettable | XvGettable, 0, 12, "XV_ENCODING"},
47643df4709Smrg   {XvSettable | XvGettable, 0, -1, "XV_FREQ"},
47743df4709Smrg   {             XvGettable, -1000, 1000, "XV_TUNER_STATUS"},
47843df4709Smrg   {XvSettable | XvGettable, -1000, 1000, "XV_VOLUME"},
47943df4709Smrg   {XvSettable | XvGettable, 0, 1, "XV_MUTE"},
48043df4709Smrg   {XvSettable | XvGettable, 0, 1, "XV_SAP"},
48143df4709Smrg   {XvSettable | XvGettable, 0, 0x1F, "XV_DEBUG_ADJUSTMENT"},
48243df4709Smrg   { 0, 0, 0, NULL}  /* just a place holder so I don't have to be fancy with commas */
48343df4709Smrg};
48443df4709Smrg
48543df4709Smrg
48643df4709Smrg#define INCLUDE_RGB_FORMATS 1
48743df4709Smrg
48843df4709Smrg#if INCLUDE_RGB_FORMATS
48943df4709Smrg
49043df4709Smrg#define NUM_IMAGES 8
49143df4709Smrg
49243df4709Smrg/* Note: GUIDs are bogus... - but nothing uses them anyway */
49343df4709Smrg
49443df4709Smrg#define FOURCC_RGBA32   0x41424752
49543df4709Smrg
49643df4709Smrg#define XVIMAGE_RGBA32(byte_order)   \
49743df4709Smrg        { \
49843df4709Smrg                FOURCC_RGBA32, \
49943df4709Smrg                XvRGB, \
50043df4709Smrg                byte_order, \
50143df4709Smrg                { 'R', 'G', 'B', 'A', \
50243df4709Smrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
50343df4709Smrg                32, \
50443df4709Smrg                XvPacked, \
50543df4709Smrg                1, \
50643df4709Smrg                32, 0x00FF0000, 0x0000FF00, 0x000000FF, \
50743df4709Smrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
50843df4709Smrg                {'A', 'R', 'G', 'B', \
50943df4709Smrg                  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}, \
51043df4709Smrg                XvTopToBottom \
51143df4709Smrg        }
51243df4709Smrg
51343df4709Smrg#define FOURCC_RGB24    0x00000000
51443df4709Smrg
51543df4709Smrg#define XVIMAGE_RGB24   \
51643df4709Smrg        { \
51743df4709Smrg                FOURCC_RGB24, \
51843df4709Smrg                XvRGB, \
51943df4709Smrg                LSBFirst, \
52043df4709Smrg                { 'R', 'G', 'B', 0, \
52143df4709Smrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
52243df4709Smrg                24, \
52343df4709Smrg                XvPacked, \
52443df4709Smrg                1, \
52543df4709Smrg                24, 0x00FF0000, 0x0000FF00, 0x000000FF, \
52643df4709Smrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
52743df4709Smrg                { 'R', 'G', 'B', \
52843df4709Smrg                  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}, \
52943df4709Smrg                XvTopToBottom \
53043df4709Smrg        }
53143df4709Smrg
53243df4709Smrg#define FOURCC_RGBT16   0x54424752
53343df4709Smrg
53443df4709Smrg#define XVIMAGE_RGBT16(byte_order)   \
53543df4709Smrg        { \
53643df4709Smrg                FOURCC_RGBT16, \
53743df4709Smrg                XvRGB, \
53843df4709Smrg                byte_order, \
53943df4709Smrg                { 'R', 'G', 'B', 'T', \
54043df4709Smrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
54143df4709Smrg                16, \
54243df4709Smrg                XvPacked, \
54343df4709Smrg                1, \
54443df4709Smrg                16, 0x00007C00, 0x000003E0, 0x0000001F, \
54543df4709Smrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
54643df4709Smrg                {'A', 'R', 'G', 'B', \
54743df4709Smrg                  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}, \
54843df4709Smrg                XvTopToBottom \
54943df4709Smrg        }
550209ff23fSmrg
55143df4709Smrg#define FOURCC_RGB16    0x32424752
55243df4709Smrg
55343df4709Smrg#define XVIMAGE_RGB16(byte_order)   \
55443df4709Smrg        { \
55543df4709Smrg                FOURCC_RGB16, \
55643df4709Smrg                XvRGB, \
55743df4709Smrg                byte_order, \
55843df4709Smrg                { 'R', 'G', 'B', 0x00, \
55943df4709Smrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
56043df4709Smrg                16, \
56143df4709Smrg                XvPacked, \
56243df4709Smrg                1, \
56343df4709Smrg                16, 0x0000F800, 0x000007E0, 0x0000001F, \
56443df4709Smrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
56543df4709Smrg                {'R', 'G', 'B', \
56643df4709Smrg                  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}, \
56743df4709Smrg                XvTopToBottom \
56843df4709Smrg        }
56943df4709Smrg
57043df4709Smrgstatic XF86ImageRec Images[NUM_IMAGES] =
57143df4709Smrg{
5726322c902Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
57343df4709Smrg        XVIMAGE_RGBA32(MSBFirst),
57443df4709Smrg        XVIMAGE_RGBT16(MSBFirst),
57543df4709Smrg        XVIMAGE_RGB16(MSBFirst),
57643df4709Smrg#else
57743df4709Smrg        XVIMAGE_RGBA32(LSBFirst),
57843df4709Smrg        XVIMAGE_RGBT16(LSBFirst),
57943df4709Smrg        XVIMAGE_RGB16(LSBFirst),
5806322c902Smrg#endif
58143df4709Smrg        XVIMAGE_RGB24,
58243df4709Smrg        XVIMAGE_YUY2,
58343df4709Smrg        XVIMAGE_UYVY,
58443df4709Smrg        XVIMAGE_YV12,
58543df4709Smrg        XVIMAGE_I420
58643df4709Smrg};
587209ff23fSmrg
58843df4709Smrg#else
589209ff23fSmrg
59043df4709Smrg#define NUM_IMAGES 4
59143df4709Smrg
59243df4709Smrgstatic XF86ImageRec Images[NUM_IMAGES] =
59343df4709Smrg{
59443df4709Smrg    XVIMAGE_YUY2,
59543df4709Smrg    XVIMAGE_UYVY,
59643df4709Smrg    XVIMAGE_YV12,
59743df4709Smrg    XVIMAGE_I420
59843df4709Smrg};
59943df4709Smrg
60043df4709Smrg#endif
60143df4709Smrg
60243df4709Smrg/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
60343df4709Smrgstatic REF_TRANSFORM trans[2] =
60443df4709Smrg{
60543df4709Smrg    {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
60643df4709Smrg    {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0}  /* BT.709 */
60743df4709Smrg};
60843df4709Smrg
60943df4709Smrg/* Gamma curve definition for preset gammas */
61043df4709Smrgtypedef struct tagGAMMA_CURVE_R100
61143df4709Smrg{
61243df4709Smrg    uint32_t GAMMA_0_F_SLOPE;
61343df4709Smrg    uint32_t GAMMA_0_F_OFFSET;
61443df4709Smrg    uint32_t GAMMA_10_1F_SLOPE;
61543df4709Smrg    uint32_t GAMMA_10_1F_OFFSET;
61643df4709Smrg    uint32_t GAMMA_20_3F_SLOPE;
61743df4709Smrg    uint32_t GAMMA_20_3F_OFFSET;
61843df4709Smrg    uint32_t GAMMA_40_7F_SLOPE;
61943df4709Smrg    uint32_t GAMMA_40_7F_OFFSET;
62043df4709Smrg    uint32_t GAMMA_380_3BF_SLOPE;
62143df4709Smrg    uint32_t GAMMA_380_3BF_OFFSET;
62243df4709Smrg    uint32_t GAMMA_3C0_3FF_SLOPE;
62343df4709Smrg    uint32_t GAMMA_3C0_3FF_OFFSET;
62443df4709Smrg    float OvGammaCont;
62543df4709Smrg} GAMMA_CURVE_R100;
62643df4709Smrg
62743df4709Smrgtypedef struct tagGAMMA_CURVE_R200
62843df4709Smrg{
62943df4709Smrg    uint32_t GAMMA_0_F_SLOPE;
63043df4709Smrg    uint32_t GAMMA_0_F_OFFSET;
63143df4709Smrg    uint32_t GAMMA_10_1F_SLOPE;
63243df4709Smrg    uint32_t GAMMA_10_1F_OFFSET;
63343df4709Smrg    uint32_t GAMMA_20_3F_SLOPE;
63443df4709Smrg    uint32_t GAMMA_20_3F_OFFSET;
63543df4709Smrg    uint32_t GAMMA_40_7F_SLOPE;
63643df4709Smrg    uint32_t GAMMA_40_7F_OFFSET;
63743df4709Smrg    uint32_t GAMMA_80_BF_SLOPE;
63843df4709Smrg    uint32_t GAMMA_80_BF_OFFSET;
63943df4709Smrg    uint32_t GAMMA_C0_FF_SLOPE;
64043df4709Smrg    uint32_t GAMMA_C0_FF_OFFSET;
64143df4709Smrg    uint32_t GAMMA_100_13F_SLOPE;
64243df4709Smrg    uint32_t GAMMA_100_13F_OFFSET;
64343df4709Smrg    uint32_t GAMMA_140_17F_SLOPE;
64443df4709Smrg    uint32_t GAMMA_140_17F_OFFSET;
64543df4709Smrg    uint32_t GAMMA_180_1BF_SLOPE;
64643df4709Smrg    uint32_t GAMMA_180_1BF_OFFSET;
64743df4709Smrg    uint32_t GAMMA_1C0_1FF_SLOPE;
64843df4709Smrg    uint32_t GAMMA_1C0_1FF_OFFSET;
64943df4709Smrg    uint32_t GAMMA_200_23F_SLOPE;
65043df4709Smrg    uint32_t GAMMA_200_23F_OFFSET;
65143df4709Smrg    uint32_t GAMMA_240_27F_SLOPE;
65243df4709Smrg    uint32_t GAMMA_240_27F_OFFSET;
65343df4709Smrg    uint32_t GAMMA_280_2BF_SLOPE;
65443df4709Smrg    uint32_t GAMMA_280_2BF_OFFSET;
65543df4709Smrg    uint32_t GAMMA_2C0_2FF_SLOPE;
65643df4709Smrg    uint32_t GAMMA_2C0_2FF_OFFSET;
65743df4709Smrg    uint32_t GAMMA_300_33F_SLOPE;
65843df4709Smrg    uint32_t GAMMA_300_33F_OFFSET;
65943df4709Smrg    uint32_t GAMMA_340_37F_SLOPE;
66043df4709Smrg    uint32_t GAMMA_340_37F_OFFSET;
66143df4709Smrg    uint32_t GAMMA_380_3BF_SLOPE;
66243df4709Smrg    uint32_t GAMMA_380_3BF_OFFSET;
66343df4709Smrg    uint32_t GAMMA_3C0_3FF_SLOPE;
66443df4709Smrg    uint32_t GAMMA_3C0_3FF_OFFSET;
66543df4709Smrg    float OvGammaCont;
66643df4709Smrg} GAMMA_CURVE_R200;
66743df4709Smrg
66843df4709Smrg
66943df4709Smrg/* Preset gammas */
67043df4709Smrgstatic GAMMA_CURVE_R100 gamma_curve_r100[8] =
67143df4709Smrg{
67243df4709Smrg	/* Gamma 1.0 */
67343df4709Smrg	{0x100, 0x0,
67443df4709Smrg	 0x100, 0x20,
67543df4709Smrg	 0x100, 0x40,
67643df4709Smrg	 0x100, 0x80,
67743df4709Smrg	 0x100, 0x100,
67843df4709Smrg	 0x100, 0x100,
67943df4709Smrg	 1.0},
68043df4709Smrg	/* Gamma 0.85 */
68143df4709Smrg	{0x75,  0x0,
68243df4709Smrg	 0xA2,  0xF,
68343df4709Smrg	 0xAC,  0x23,
68443df4709Smrg	 0xC6,  0x4E,
68543df4709Smrg	 0x129, 0xD6,
68643df4709Smrg	 0x12B, 0xD5,
68743df4709Smrg	 1.0},
68843df4709Smrg	/* Gamma 1.1 */
68943df4709Smrg	{0x180, 0x0,
69043df4709Smrg	 0x13C, 0x30,
69143df4709Smrg	 0x13C, 0x57,
69243df4709Smrg	 0x123, 0xA5,
69343df4709Smrg	 0xEA,  0x116,
69443df4709Smrg	 0xEA, 0x116,
69543df4709Smrg	 0.9913},
69643df4709Smrg	/* Gamma 1.2 */
69743df4709Smrg	{0x21B, 0x0,
69843df4709Smrg	 0x16D, 0x43,
69943df4709Smrg	 0x172, 0x71,
70043df4709Smrg	 0x13D, 0xCD,
70143df4709Smrg	 0xD9,  0x128,
70243df4709Smrg	 0xD6, 0x12A,
70343df4709Smrg	 0.9827},
70443df4709Smrg	/* Gamma 1.45 */
70543df4709Smrg	{0x404, 0x0,
70643df4709Smrg	 0x1B9, 0x81,
70743df4709Smrg	 0x1EE, 0xB8,
70843df4709Smrg	 0x16A, 0x133,
70943df4709Smrg	 0xB7, 0x14B,
71043df4709Smrg	 0xB2, 0x14E,
71143df4709Smrg	 0.9567},
71243df4709Smrg	/* Gamma 1.7 */
71343df4709Smrg	{0x658, 0x0,
71443df4709Smrg	 0x1B5, 0xCB,
71543df4709Smrg	 0x25F, 0x102,
71643df4709Smrg	 0x181, 0x199,
71743df4709Smrg	 0x9C,  0x165,
71843df4709Smrg	 0x98, 0x167,
71943df4709Smrg	 0.9394},
72043df4709Smrg	/* Gamma 2.2 */
72143df4709Smrg	{0x7FF, 0x0,
72243df4709Smrg	 0x625, 0x100,
72343df4709Smrg	 0x1E4, 0x1C4,
72443df4709Smrg	 0x1BD, 0x23D,
72543df4709Smrg	 0x79,  0x187,
72643df4709Smrg	 0x76,  0x188,
72743df4709Smrg	 0.9135},
72843df4709Smrg	/* Gamma 2.5 */
72943df4709Smrg	{0x7FF, 0x0,
73043df4709Smrg	 0x7FF, 0x100,
73143df4709Smrg	 0x2AD, 0x200,
73243df4709Smrg	 0x1A2, 0x2AB,
73343df4709Smrg	 0x6E,  0x194,
73443df4709Smrg	 0x67,  0x197,
73543df4709Smrg	 0.9135}
73643df4709Smrg};
73743df4709Smrg
73843df4709Smrgstatic GAMMA_CURVE_R200 gamma_curve_r200[8] =
73943df4709Smrg {
74043df4709Smrg	/* Gamma 1.0 */
74143df4709Smrg      {0x00000100, 0x00000000,
74243df4709Smrg       0x00000100, 0x00000020,
74343df4709Smrg       0x00000100, 0x00000040,
74443df4709Smrg       0x00000100, 0x00000080,
74543df4709Smrg       0x00000100, 0x00000100,
74643df4709Smrg       0x00000100, 0x00000100,
74743df4709Smrg       0x00000100, 0x00000200,
74843df4709Smrg       0x00000100, 0x00000200,
74943df4709Smrg       0x00000100, 0x00000300,
75043df4709Smrg       0x00000100, 0x00000300,
75143df4709Smrg       0x00000100, 0x00000400,
75243df4709Smrg       0x00000100, 0x00000400,
75343df4709Smrg       0x00000100, 0x00000500,
75443df4709Smrg       0x00000100, 0x00000500,
75543df4709Smrg       0x00000100, 0x00000600,
75643df4709Smrg       0x00000100, 0x00000600,
75743df4709Smrg       0x00000100, 0x00000700,
75843df4709Smrg       0x00000100, 0x00000700,
75943df4709Smrg       1.0},
76043df4709Smrg	/* Gamma 0.85 */
76143df4709Smrg      {0x0000001D, 0x00000000,
76243df4709Smrg       0x00000028, 0x0000000F,
76343df4709Smrg       0x00000056, 0x00000023,
76443df4709Smrg       0x000000C5, 0x0000004E,
76543df4709Smrg       0x000000DA, 0x000000B0,
76643df4709Smrg       0x000000E6, 0x000000AA,
76743df4709Smrg       0x000000F1, 0x00000190,
76843df4709Smrg       0x000000F9, 0x0000018C,
76943df4709Smrg       0x00000101, 0x00000286,
77043df4709Smrg       0x00000108, 0x00000282,
77143df4709Smrg       0x0000010D, 0x0000038A,
77243df4709Smrg       0x00000113, 0x00000387,
77343df4709Smrg       0x00000118, 0x0000049A,
77443df4709Smrg       0x0000011C, 0x00000498,
77543df4709Smrg       0x00000120, 0x000005B4,
77643df4709Smrg       0x00000124, 0x000005B2,
77743df4709Smrg       0x00000128, 0x000006D6,
77843df4709Smrg       0x0000012C, 0x000006D5,
77943df4709Smrg       1.0},
78043df4709Smrg	/* Gamma 1.1 */
78143df4709Smrg      {0x00000060, 0x00000000,
78243df4709Smrg       0x0000004F, 0x00000030,
78343df4709Smrg       0x0000009C, 0x00000057,
78443df4709Smrg       0x00000121, 0x000000A5,
78543df4709Smrg       0x00000113, 0x00000136,
78643df4709Smrg       0x0000010B, 0x0000013A,
78743df4709Smrg       0x00000105, 0x00000245,
78843df4709Smrg       0x00000100, 0x00000247,
78943df4709Smrg       0x000000FD, 0x00000348,
79043df4709Smrg       0x000000F9, 0x00000349,
79143df4709Smrg       0x000000F6, 0x00000443,
79243df4709Smrg       0x000000F4, 0x00000444,
79343df4709Smrg       0x000000F2, 0x00000538,
79443df4709Smrg       0x000000F0, 0x00000539,
79543df4709Smrg       0x000000EE, 0x00000629,
79643df4709Smrg       0x000000EC, 0x00000629,
79743df4709Smrg       0x000000EB, 0x00000716,
79843df4709Smrg       0x000000E9, 0x00000717,
79943df4709Smrg       0.9913},
80043df4709Smrg	/* Gamma 1.2 */
80143df4709Smrg      {0x00000087, 0x00000000,
80243df4709Smrg       0x0000005B, 0x00000043,
80343df4709Smrg       0x000000B7, 0x00000071,
80443df4709Smrg       0x0000013D, 0x000000CD,
80543df4709Smrg       0x00000121, 0x0000016B,
80643df4709Smrg       0x00000113, 0x00000172,
80743df4709Smrg       0x00000107, 0x00000286,
80843df4709Smrg       0x000000FF, 0x0000028A,
80943df4709Smrg       0x000000F8, 0x00000389,
81043df4709Smrg       0x000000F2, 0x0000038B,
81143df4709Smrg       0x000000ED, 0x0000047D,
81243df4709Smrg       0x000000E9, 0x00000480,
81343df4709Smrg       0x000000E5, 0x00000568,
81443df4709Smrg       0x000000E1, 0x0000056A,
81543df4709Smrg       0x000000DE, 0x0000064B,
81643df4709Smrg       0x000000DB, 0x0000064D,
81743df4709Smrg       0x000000D9, 0x00000728,
81843df4709Smrg       0x000000D6, 0x00000729,
81943df4709Smrg       0.9827},
82043df4709Smrg	/* Gamma 1.45 */
82143df4709Smrg      {0x00000101, 0x00000000,
82243df4709Smrg       0x0000006E, 0x00000081,
82343df4709Smrg       0x000000F7, 0x000000B8,
82443df4709Smrg       0x0000016E, 0x00000133,
82543df4709Smrg       0x00000139, 0x000001EA,
82643df4709Smrg       0x0000011B, 0x000001F9,
82743df4709Smrg       0x00000105, 0x00000314,
82843df4709Smrg       0x000000F6, 0x0000031C,
82943df4709Smrg       0x000000E9, 0x00000411,
83043df4709Smrg       0x000000DF, 0x00000417,
83143df4709Smrg       0x000000D7, 0x000004F6,
83243df4709Smrg       0x000000CF, 0x000004F9,
83343df4709Smrg       0x000000C9, 0x000005C9,
83443df4709Smrg       0x000000C4, 0x000005CC,
83543df4709Smrg       0x000000BF, 0x0000068F,
83643df4709Smrg       0x000000BA, 0x00000691,
83743df4709Smrg       0x000000B6, 0x0000074B,
83843df4709Smrg       0x000000B2, 0x0000074D,
83943df4709Smrg       0.9567},
84043df4709Smrg	/* Gamma 1.7 */
84143df4709Smrg      {0x00000196, 0x00000000,
84243df4709Smrg       0x0000006D, 0x000000CB,
84343df4709Smrg       0x0000012F, 0x00000102,
84443df4709Smrg       0x00000187, 0x00000199,
84543df4709Smrg       0x00000144, 0x0000025b,
84643df4709Smrg       0x00000118, 0x00000273,
84743df4709Smrg       0x000000FE, 0x0000038B,
84843df4709Smrg       0x000000E9, 0x00000395,
84943df4709Smrg       0x000000DA, 0x0000047E,
85043df4709Smrg       0x000000CE, 0x00000485,
85143df4709Smrg       0x000000C3, 0x00000552,
85243df4709Smrg       0x000000BB, 0x00000556,
85343df4709Smrg       0x000000B3, 0x00000611,
85443df4709Smrg       0x000000AC, 0x00000614,
85543df4709Smrg       0x000000A7, 0x000006C1,
85643df4709Smrg       0x000000A1, 0x000006C3,
85743df4709Smrg       0x0000009D, 0x00000765,
85843df4709Smrg       0x00000098, 0x00000767,
85943df4709Smrg       0.9394},
86043df4709Smrg	/* Gamma 2.2 */
86143df4709Smrg      {0x000001FF, 0x00000000,
86243df4709Smrg       0x0000018A, 0x00000100,
86343df4709Smrg       0x000000F1, 0x000001C5,
86443df4709Smrg       0x000001D6, 0x0000023D,
86543df4709Smrg       0x00000124, 0x00000328,
86643df4709Smrg       0x00000116, 0x0000032F,
86743df4709Smrg       0x000000E2, 0x00000446,
86843df4709Smrg       0x000000D3, 0x0000044D,
86943df4709Smrg       0x000000BC, 0x00000520,
87043df4709Smrg       0x000000B0, 0x00000526,
87143df4709Smrg       0x000000A4, 0x000005D6,
87243df4709Smrg       0x0000009B, 0x000005DB,
87343df4709Smrg       0x00000092, 0x00000676,
87443df4709Smrg       0x0000008B, 0x00000679,
87543df4709Smrg       0x00000085, 0x00000704,
87643df4709Smrg       0x00000080, 0x00000707,
87743df4709Smrg       0x0000007B, 0x00000787,
87843df4709Smrg       0x00000076, 0x00000789,
87943df4709Smrg       0.9135},
88043df4709Smrg	/* Gamma 2.5 */
88143df4709Smrg      {0x000001FF, 0x00000000,
88243df4709Smrg       0x000001FF, 0x00000100,
88343df4709Smrg       0x00000159, 0x000001FF,
88443df4709Smrg       0x000001AC, 0x000002AB,
88543df4709Smrg       0x0000012F, 0x00000381,
88643df4709Smrg       0x00000101, 0x00000399,
88743df4709Smrg       0x000000D9, 0x0000049A,
88843df4709Smrg       0x000000C3, 0x000004A5,
88943df4709Smrg       0x000000AF, 0x00000567,
89043df4709Smrg       0x000000A1, 0x0000056E,
89143df4709Smrg       0x00000095, 0x00000610,
89243df4709Smrg       0x0000008C, 0x00000614,
89343df4709Smrg       0x00000084, 0x000006A0,
89443df4709Smrg       0x0000007D, 0x000006A4,
89543df4709Smrg       0x00000077, 0x00000721,
89643df4709Smrg       0x00000071, 0x00000723,
89743df4709Smrg       0x0000006D, 0x00000795,
89843df4709Smrg       0x00000068, 0x00000797,
89943df4709Smrg       0.9135}
90043df4709Smrg};
90143df4709Smrg
90243df4709Smrgstatic void
90343df4709SmrgRADEONSetOverlayGamma(ScrnInfoPtr pScrn, uint32_t gamma)
90443df4709Smrg{
90543df4709Smrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
90643df4709Smrg    unsigned char   *RADEONMMIO = info->MMIO;
90743df4709Smrg
90843df4709Smrg    /* Set gamma */
90943df4709Smrg    RADEONWaitForIdleMMIO(pScrn);
91043df4709Smrg
91143df4709Smrg    if (info->ChipFamily < CHIP_FAMILY_R200) {
91243df4709Smrg	uint32_t ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL) & ~RADEON_SCALER_GAMMA_SEL_MASK;
91343df4709Smrg	OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 5));
91443df4709Smrg    }
91543df4709Smrg
91643df4709Smrg    /* Load gamma curve adjustments */
91743df4709Smrg    if (info->ChipFamily >= CHIP_FAMILY_R200) {
91843df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_000_00F,
91943df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
92043df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010));
92143df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_010_01F,
92243df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
92343df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
92443df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_020_03F,
92543df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
92643df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
92743df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_040_07F,
92843df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
92943df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
93043df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_080_0BF,
93143df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_80_BF_OFFSET << 0x00000000) |
93243df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_80_BF_SLOPE << 0x00000010));
93343df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_0C0_0FF,
93443df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_C0_FF_OFFSET << 0x00000000) |
93543df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_C0_FF_SLOPE << 0x00000010));
93643df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_100_13F,
93743df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_100_13F_OFFSET << 0x00000000) |
93843df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_100_13F_SLOPE << 0x00000010));
93943df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_140_17F,
94043df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_140_17F_OFFSET << 0x00000000) |
94143df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_140_17F_SLOPE << 0x00000010));
94243df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_180_1BF,
94343df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_180_1BF_OFFSET << 0x00000000) |
94443df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_180_1BF_SLOPE << 0x00000010));
94543df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_1C0_1FF,
94643df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_OFFSET << 0x00000000) |
94743df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_SLOPE << 0x00000010));
94843df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_200_23F,
94943df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_200_23F_OFFSET << 0x00000000) |
95043df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_200_23F_SLOPE << 0x00000010));
95143df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_240_27F,
95243df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_240_27F_OFFSET << 0x00000000) |
95343df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_240_27F_SLOPE << 0x00000010));
95443df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_280_2BF,
95543df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_280_2BF_OFFSET << 0x00000000) |
95643df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_280_2BF_SLOPE << 0x00000010));
95743df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_2C0_2FF,
95843df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_OFFSET << 0x00000000) |
95943df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_SLOPE << 0x00000010));
96043df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_300_33F,
96143df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_300_33F_OFFSET << 0x00000000) |
96243df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_300_33F_SLOPE << 0x00000010));
96343df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_340_37F,
96443df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_340_37F_OFFSET << 0x00000000) |
96543df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_340_37F_SLOPE << 0x00000010));
96643df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_380_3BF,
96743df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
96843df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
96943df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
97043df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
97143df4709Smrg	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
97243df4709Smrg    } else {
97343df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_000_00F,
97443df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
97543df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_0_F_SLOPE << 0x00000010));
97643df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_010_01F,
97743df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
97843df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
97943df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_020_03F,
98043df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
98143df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
98243df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_040_07F,
98343df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
98443df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
98543df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_380_3BF,
98643df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
98743df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
98843df4709Smrg    	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
98943df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
99043df4709Smrg	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
99143df4709Smrg    }
99243df4709Smrg
99343df4709Smrg}
99443df4709Smrg
99543df4709Smrgstatic uint32_t
99643df4709SmrgRADEONTranslateUserGamma(uint32_t user_gamma)
99743df4709Smrg{
99843df4709Smrg    /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
99943df4709Smrg    if (user_gamma <= 925)       /* 0.85 */
100043df4709Smrg	return 1;
100143df4709Smrg    else if (user_gamma <= 1050) /* 1.0  */
100243df4709Smrg	return 0;
100343df4709Smrg    else if (user_gamma <= 1150) /* 1.1  */
100443df4709Smrg	return 2;
100543df4709Smrg    else if (user_gamma <= 1325) /* 1.2  */
100643df4709Smrg	return 3;
100743df4709Smrg    else if (user_gamma <= 1575) /* 1.45 */
100843df4709Smrg	return 4;
100943df4709Smrg    else if (user_gamma <= 1950) /* 1.7  */
101043df4709Smrg	return 5;
101143df4709Smrg    else if (user_gamma <= 2350) /* 2.2  */
101243df4709Smrg	return 6;
101343df4709Smrg    else if (user_gamma > 2350)  /* 2.5  */
101443df4709Smrg	return 7;
101543df4709Smrg    else
101643df4709Smrg	return 0;
101743df4709Smrg}
101843df4709Smrg
101943df4709Smrg
102043df4709Smrg/****************************************************************************
102143df4709Smrg * SetTransform                                                             *
102243df4709Smrg *  Function: Calculates and sets color space transform from supplied       *
102343df4709Smrg *            reference transform, gamma, brightness, contrast, hue and     *
102443df4709Smrg *            saturation.                                                   *
102543df4709Smrg *    Inputs: bright - brightness                                           *
102643df4709Smrg *            cont - contrast                                               *
102743df4709Smrg *            sat - saturation                                              *
102843df4709Smrg *            hue - hue                                                     *
102943df4709Smrg *            red_intensity - intensity of red component                    *
103043df4709Smrg *            green_intensity - intensity of green component                *
103143df4709Smrg *            blue_intensity - intensity of blue component                  *
103243df4709Smrg *            ref - index to the table of refernce transforms               *
103343df4709Smrg *            user_gamma - gamma value x 1000 (e.g., 1200 = gamma of 1.2)   *
103443df4709Smrg *   Outputs: NONE                                                          *
103543df4709Smrg ****************************************************************************/
103643df4709Smrg
103743df4709Smrgstatic void RADEONSetTransform (ScrnInfoPtr pScrn,
103843df4709Smrg				float	    bright,
103943df4709Smrg				float	    cont,
104043df4709Smrg				float	    sat,
104143df4709Smrg				float	    hue,
104243df4709Smrg				float	    red_intensity,
104343df4709Smrg				float	    green_intensity,
104443df4709Smrg				float	    blue_intensity,
104543df4709Smrg				uint32_t    ref,
104643df4709Smrg				uint32_t    user_gamma)
104743df4709Smrg{
104843df4709Smrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
104943df4709Smrg    unsigned char   *RADEONMMIO = info->MMIO;
105043df4709Smrg    float	    OvHueSin, OvHueCos;
105143df4709Smrg    float	    CAdjLuma, CAdjOff;
105243df4709Smrg    float	    CAdjRCb, CAdjRCr;
105343df4709Smrg    float	    CAdjGCb, CAdjGCr;
105443df4709Smrg    float	    CAdjBCb, CAdjBCr;
105543df4709Smrg    float	    RedAdj,GreenAdj,BlueAdj;
105643df4709Smrg    float	    OvLuma, OvROff, OvGOff, OvBOff;
105743df4709Smrg    float	    OvRCb, OvRCr;
105843df4709Smrg    float	    OvGCb, OvGCr;
105943df4709Smrg    float	    OvBCb, OvBCr;
106043df4709Smrg    float	    Loff = 64.0;
106143df4709Smrg    float	    Coff = 512.0f;
106243df4709Smrg
106343df4709Smrg    uint32_t	    dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff;
106443df4709Smrg    uint32_t	    dwOvRCb, dwOvRCr;
106543df4709Smrg    uint32_t	    dwOvGCb, dwOvGCr;
106643df4709Smrg    uint32_t	    dwOvBCb, dwOvBCr;
106743df4709Smrg    uint32_t	    gamma = 0;
106843df4709Smrg
106943df4709Smrg    if (ref >= 2)
107043df4709Smrg	return;
107143df4709Smrg
107243df4709Smrg    /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
107343df4709Smrg    gamma = RADEONTranslateUserGamma(user_gamma);
107443df4709Smrg
107543df4709Smrg    if (gamma >= 8)
107643df4709Smrg	return;
107743df4709Smrg
107843df4709Smrg    OvHueSin = sin(hue);
107943df4709Smrg    OvHueCos = cos(hue);
108043df4709Smrg
108143df4709Smrg    CAdjLuma = cont * trans[ref].RefLuma;
108243df4709Smrg    CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0;
108343df4709Smrg    RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0;
108443df4709Smrg    GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0;
108543df4709Smrg    BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0;
108643df4709Smrg
108743df4709Smrg    CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr;
108843df4709Smrg    CAdjRCr = sat * OvHueCos * trans[ref].RefRCr;
108943df4709Smrg    CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr);
109043df4709Smrg    CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr);
109143df4709Smrg    CAdjBCb = sat * OvHueCos * trans[ref].RefBCb;
109243df4709Smrg    CAdjBCr = sat * OvHueSin * trans[ref].RefBCb;
109343df4709Smrg
109443df4709Smrg#if 0 /* default constants */
109543df4709Smrg    CAdjLuma = 1.16455078125;
109643df4709Smrg
109743df4709Smrg    CAdjRCb = 0.0;
109843df4709Smrg    CAdjRCr = 1.59619140625;
109943df4709Smrg    CAdjGCb = -0.39111328125;
110043df4709Smrg    CAdjGCr = -0.8125;
110143df4709Smrg    CAdjBCb = 2.01708984375;
110243df4709Smrg    CAdjBCr = 0;
110343df4709Smrg#endif
110443df4709Smrg
110543df4709Smrg    OvLuma = CAdjLuma * gamma_curve_r100[gamma].OvGammaCont;
110643df4709Smrg    OvRCb = CAdjRCb * gamma_curve_r100[gamma].OvGammaCont;
110743df4709Smrg    OvRCr = CAdjRCr * gamma_curve_r100[gamma].OvGammaCont;
110843df4709Smrg    OvGCb = CAdjGCb * gamma_curve_r100[gamma].OvGammaCont;
110943df4709Smrg    OvGCr = CAdjGCr * gamma_curve_r100[gamma].OvGammaCont;
111043df4709Smrg    OvBCb = CAdjBCb * gamma_curve_r100[gamma].OvGammaCont;
111143df4709Smrg    OvBCr = CAdjBCr * gamma_curve_r100[gamma].OvGammaCont;
111243df4709Smrg    OvROff = RedAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
111343df4709Smrg	OvLuma * Loff - (OvRCb + OvRCr) * Coff;
111443df4709Smrg    OvGOff = GreenAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
111543df4709Smrg	OvLuma * Loff - (OvGCb + OvGCr) * Coff;
111643df4709Smrg    OvBOff = BlueAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
111743df4709Smrg	OvLuma * Loff - (OvBCb + OvBCr) * Coff;
111843df4709Smrg#if 0 /* default constants */
111943df4709Smrg    OvROff = -888.5;
112043df4709Smrg    OvGOff = 545;
112143df4709Smrg    OvBOff = -1104;
112243df4709Smrg#endif
112343df4709Smrg
112443df4709Smrg    OvROff = ClipValue(OvROff, -2048.0, 2047.5);
112543df4709Smrg    OvGOff = ClipValue(OvGOff, -2048.0, 2047.5);
112643df4709Smrg    OvBOff = ClipValue(OvBOff, -2048.0, 2047.5);
112743df4709Smrg    dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff;
112843df4709Smrg    dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff;
112943df4709Smrg    dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff;
113043df4709Smrg
113143df4709Smrg    if(info->ChipFamily == CHIP_FAMILY_RADEON)
113243df4709Smrg    {
113343df4709Smrg	dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17;
113443df4709Smrg	dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1;
113543df4709Smrg	dwOvRCr = (((INT32)(OvRCr * 2048.0))&0x7fff)<<17;
113643df4709Smrg	dwOvGCb = (((INT32)(OvGCb * 2048.0))&0x7fff)<<1;
113743df4709Smrg	dwOvGCr = (((INT32)(OvGCr * 2048.0))&0x7fff)<<17;
113843df4709Smrg	dwOvBCb = (((INT32)(OvBCb * 2048.0))&0x7fff)<<1;
113943df4709Smrg	dwOvBCr = (((INT32)(OvBCr * 2048.0))&0x7fff)<<17;
114043df4709Smrg    }
114143df4709Smrg    else
114243df4709Smrg    {
114343df4709Smrg	dwOvLuma = (((INT32)(OvLuma * 256.0))&0xfff)<<20;
114443df4709Smrg	dwOvRCb = (((INT32)(OvRCb * 256.0))&0xfff)<<4;
114543df4709Smrg	dwOvRCr = (((INT32)(OvRCr * 256.0))&0xfff)<<20;
114643df4709Smrg	dwOvGCb = (((INT32)(OvGCb * 256.0))&0xfff)<<4;
114743df4709Smrg	dwOvGCr = (((INT32)(OvGCr * 256.0))&0xfff)<<20;
114843df4709Smrg	dwOvBCb = (((INT32)(OvBCb * 256.0))&0xfff)<<4;
114943df4709Smrg	dwOvBCr = (((INT32)(OvBCr * 256.0))&0xfff)<<20;
115043df4709Smrg    }
115143df4709Smrg
115243df4709Smrg    /* set gamma */
115343df4709Smrg    RADEONSetOverlayGamma(pScrn, gamma);
115443df4709Smrg
115543df4709Smrg    /* color transforms */
115643df4709Smrg    OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma);
115743df4709Smrg    OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr);
115843df4709Smrg    OUTREG(RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma);
115943df4709Smrg    OUTREG(RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr);
116043df4709Smrg    OUTREG(RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma);
116143df4709Smrg    OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr);
116243df4709Smrg}
116343df4709Smrg
116443df4709Smrgstatic void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode)
116543df4709Smrg{
116643df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
116743df4709Smrg    unsigned char *RADEONMMIO = info->MMIO;
116843df4709Smrg
116943df4709Smrg    if (alpha_mode == 0) { /* key mode */
117043df4709Smrg    	OUTREG(RADEON_OV0_KEY_CNTL,
117143df4709Smrg		RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */
117243df4709Smrg		RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */
117343df4709Smrg		RADEON_CMP_MIX_OR);
117443df4709Smrg    	/* crtc 1 */
117543df4709Smrg    	OUTREG(RADEON_DISP_MERGE_CNTL,
117643df4709Smrg		(RADEON_DISP_ALPHA_MODE_KEY &
117743df4709Smrg		RADEON_DISP_ALPHA_MODE_MASK) |
117843df4709Smrg		((gr_alpha << 0x00000010) &
117943df4709Smrg		RADEON_DISP_GRPH_ALPHA_MASK) |
118043df4709Smrg		((ov_alpha << 0x00000018) &
118143df4709Smrg		RADEON_DISP_OV0_ALPHA_MASK));
118243df4709Smrg    	/* crtc 2 */
118343df4709Smrg    	OUTREG(RADEON_DISP2_MERGE_CNTL,
118443df4709Smrg		(RADEON_DISP_ALPHA_MODE_KEY &
118543df4709Smrg		RADEON_DISP_ALPHA_MODE_MASK) |
118643df4709Smrg		((gr_alpha << 0x00000010) &
118743df4709Smrg		RADEON_DISP_GRPH_ALPHA_MASK) |
118843df4709Smrg		((ov_alpha << 0x00000018) &
118943df4709Smrg		RADEON_DISP_OV0_ALPHA_MASK));
119043df4709Smrg    } else { /* global mode */
119143df4709Smrg    	OUTREG(RADEON_OV0_KEY_CNTL,
119243df4709Smrg		RADEON_GRAPHIC_KEY_FN_FALSE |   /* what does this do? */
119343df4709Smrg		RADEON_VIDEO_KEY_FN_FALSE |   /* what does this do? */
119443df4709Smrg		RADEON_CMP_MIX_AND);
119543df4709Smrg    	/* crtc 2 */
119643df4709Smrg    	OUTREG(RADEON_DISP2_MERGE_CNTL,
119743df4709Smrg		(RADEON_DISP_ALPHA_MODE_GLOBAL &
119843df4709Smrg		RADEON_DISP_ALPHA_MODE_MASK) |
119943df4709Smrg		((gr_alpha << 0x00000010) &
120043df4709Smrg		RADEON_DISP_GRPH_ALPHA_MASK) |
120143df4709Smrg		((ov_alpha << 0x00000018) &
120243df4709Smrg		RADEON_DISP_OV0_ALPHA_MASK));
120343df4709Smrg    	/* crtc 1 */
120443df4709Smrg    	OUTREG(RADEON_DISP_MERGE_CNTL,
120543df4709Smrg		(RADEON_DISP_ALPHA_MODE_GLOBAL &
120643df4709Smrg		RADEON_DISP_ALPHA_MODE_MASK) |
120743df4709Smrg		((gr_alpha << 0x00000010) &
120843df4709Smrg		RADEON_DISP_GRPH_ALPHA_MASK) |
120943df4709Smrg		((ov_alpha << 0x00000018) &
121043df4709Smrg		RADEON_DISP_OV0_ALPHA_MASK));
1211209ff23fSmrg    }
121243df4709Smrg     /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */
121343df4709Smrg     /* not yet supported */
1214209ff23fSmrg}
1215209ff23fSmrg
121643df4709Smrgstatic void RADEONSetColorKey(ScrnInfoPtr pScrn, uint32_t colorKey)
121743df4709Smrg{
121843df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
121943df4709Smrg    unsigned char *RADEONMMIO = info->MMIO;
122043df4709Smrg    uint32_t min, max;
122143df4709Smrg    uint8_t r, g, b;
122243df4709Smrg
122343df4709Smrg    if (info->CurrentLayout.depth > 8)
122443df4709Smrg    {
122543df4709Smrg	uint32_t	rbits, gbits, bbits;
122643df4709Smrg
122743df4709Smrg	rbits = (colorKey & pScrn->mask.red) >> pScrn->offset.red;
122843df4709Smrg	gbits = (colorKey & pScrn->mask.green) >> pScrn->offset.green;
122943df4709Smrg	bbits = (colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
123043df4709Smrg
123143df4709Smrg	r = rbits << (8 - pScrn->weight.red);
123243df4709Smrg	g = gbits << (8 - pScrn->weight.green);
123343df4709Smrg	b = bbits << (8 - pScrn->weight.blue);
123443df4709Smrg    }
123543df4709Smrg    else
123643df4709Smrg    {
123743df4709Smrg	uint32_t	bits;
123843df4709Smrg
123943df4709Smrg	bits = colorKey & ((1 << info->CurrentLayout.depth) - 1);
124043df4709Smrg	r = bits;
124143df4709Smrg	g = bits;
124243df4709Smrg	b = bits;
124343df4709Smrg    }
124443df4709Smrg    min = (r << 16) | (g << 8) | (b);
124543df4709Smrg    max = (0xff << 24) | (r << 16) | (g << 8) | (b);
124643df4709Smrg
124743df4709Smrg    RADEONWaitForFifo(pScrn, 2);
124843df4709Smrg    OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max);
124943df4709Smrg    OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min);
125043df4709Smrg}
1251209ff23fSmrg
1252209ff23fSmrgvoid
125343df4709SmrgRADEONResetVideo(ScrnInfoPtr pScrn)
125443df4709Smrg{
125543df4709Smrg    RADEONInfoPtr   info      = RADEONPTR(pScrn);
125643df4709Smrg    unsigned char *RADEONMMIO = info->MMIO;
125743df4709Smrg    RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
125843df4709Smrg    char tmp[200];
125943df4709Smrg
126043df4709Smrg    /* this function is called from ScreenInit. pScreen is used
126143df4709Smrg       by XAA internally, but not valid until ScreenInit finishs.
126243df4709Smrg    */
126343df4709Smrg    if (info->accelOn && pScrn->pScreen)
126443df4709Smrg	RADEON_SYNC(info, pScrn);
126543df4709Smrg
126643df4709Smrg    /* this is done here because each time the server is reset these
126743df4709Smrg       could change.. Otherwise they remain constant */
126843df4709Smrg    xvInstanceID = MAKE_ATOM("XV_INSTANCE_ID");
126943df4709Smrg    xvDeviceID = MAKE_ATOM("XV_DEVICE_ID");
127043df4709Smrg    xvLocationID = MAKE_ATOM("XV_LOCATION_ID");
127143df4709Smrg    xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS");
127243df4709Smrg
127343df4709Smrg    xvBrightness   = MAKE_ATOM("XV_BRIGHTNESS");
127443df4709Smrg    xvSaturation   = MAKE_ATOM("XV_SATURATION");
127543df4709Smrg    xvColor        = MAKE_ATOM("XV_COLOR");
127643df4709Smrg    xvContrast     = MAKE_ATOM("XV_CONTRAST");
127743df4709Smrg    xvColorKey     = MAKE_ATOM("XV_COLORKEY");
127843df4709Smrg    xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
127943df4709Smrg    xvHue          = MAKE_ATOM("XV_HUE");
128043df4709Smrg    xvRedIntensity   = MAKE_ATOM("XV_RED_INTENSITY");
128143df4709Smrg    xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY");
128243df4709Smrg    xvBlueIntensity  = MAKE_ATOM("XV_BLUE_INTENSITY");
128343df4709Smrg    xvGamma          = MAKE_ATOM("XV_GAMMA");
128443df4709Smrg    xvColorspace     = MAKE_ATOM("XV_COLORSPACE");
128543df4709Smrg
128643df4709Smrg    xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
128743df4709Smrg    xvSetDefaults       = MAKE_ATOM("XV_SET_DEFAULTS");
128843df4709Smrg    xvCRTC              = MAKE_ATOM("XV_CRTC");
128943df4709Smrg
129043df4709Smrg    xvOvAlpha	      = MAKE_ATOM("XV_OVERLAY_ALPHA");
129143df4709Smrg    xvGrAlpha	      = MAKE_ATOM("XV_GRAPHICS_ALPHA");
129243df4709Smrg    xvAlphaMode       = MAKE_ATOM("XV_ALPHA_MODE");
129343df4709Smrg
129443df4709Smrg    xvOverlayDeinterlacingMethod = MAKE_ATOM("XV_OVERLAY_DEINTERLACING_METHOD");
129543df4709Smrg
129643df4709Smrg    xvDecBrightness   = MAKE_ATOM("XV_DEC_BRIGHTNESS");
129743df4709Smrg    xvDecSaturation   = MAKE_ATOM("XV_DEC_SATURATION");
129843df4709Smrg    xvDecColor        = MAKE_ATOM("XV_DEC_COLOR");
129943df4709Smrg    xvDecContrast     = MAKE_ATOM("XV_DEC_CONTRAST");
130043df4709Smrg    xvDecHue          = MAKE_ATOM("XV_DEC_HUE");
130143df4709Smrg
130243df4709Smrg    xvEncoding        = MAKE_ATOM("XV_ENCODING");
130343df4709Smrg    xvFrequency       = MAKE_ATOM("XV_FREQ");
130443df4709Smrg    xvTunerStatus     = MAKE_ATOM("XV_TUNER_STATUS");
130543df4709Smrg    xvVolume          = MAKE_ATOM("XV_VOLUME");
130643df4709Smrg    xvMute            = MAKE_ATOM("XV_MUTE");
130743df4709Smrg    xvSAP             = MAKE_ATOM("XV_SAP");
130843df4709Smrg
130943df4709Smrg    xvAdjustment      = MAKE_ATOM("XV_DEBUG_ADJUSTMENT");
131043df4709Smrg
131143df4709Smrg    sprintf(tmp, "RXXX:%d.%d.%d", PCI_DEV_VENDOR_ID(info->PciInfo),
131243df4709Smrg	    PCI_DEV_DEVICE_ID(info->PciInfo), PCI_DEV_REVISION(info->PciInfo));
131343df4709Smrg    pPriv->device_id = MAKE_ATOM(tmp);
131443df4709Smrg    sprintf(tmp, "PCI:%02d:%02d.%d", PCI_DEV_BUS(info->PciInfo),
131543df4709Smrg	    PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo));
131643df4709Smrg    pPriv->location_id = MAKE_ATOM(tmp);
131743df4709Smrg    sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex);
131843df4709Smrg    pPriv->instance_id = MAKE_ATOM(tmp);
131943df4709Smrg
132043df4709Smrg    OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOFT_RESET);
132143df4709Smrg    OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0);   /* maybe */
132243df4709Smrg    OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0);
132343df4709Smrg    OUTREG(RADEON_OV0_FILTER_CNTL, RADEON_FILTER_PROGRAMMABLE_COEF);
132443df4709Smrg    OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ |
132543df4709Smrg				RADEON_VIDEO_KEY_FN_FALSE |
132643df4709Smrg				RADEON_CMP_MIX_OR);
132743df4709Smrg    OUTREG(RADEON_OV0_TEST, 0);
132843df4709Smrg    OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
132943df4709Smrg    OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
133043df4709Smrg    RADEONSetColorKey(pScrn, pPriv->colorKey);
133143df4709Smrg
133243df4709Smrg    if (info->ChipFamily == CHIP_FAMILY_RADEON) {
133343df4709Smrg
133443df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000);
133543df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e);
133643df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0);
133743df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442);
133843df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040);
133943df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
134043df4709Smrg
134143df4709Smrg    } else {
134243df4709Smrg
134343df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000);
134443df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e);
134543df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da);
134643df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442);
134743df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046);
134843df4709Smrg	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
134943df4709Smrg    }
135043df4709Smrg	/*
135143df4709Smrg	 * Set default Gamma ramp:
135243df4709Smrg	 *
135343df4709Smrg	 * Of 18 segments for gamma curve, all segments in R200 (and
135443df4709Smrg	 * newer) are programmable, while only lower 4 and upper 2
135543df4709Smrg	 * segments are programmable in the older Radeons.
135643df4709Smrg	 */
135743df4709Smrg
135843df4709Smrg    RADEONSetOverlayGamma(pScrn, 0); /* gamma = 1.0 */
135943df4709Smrg
136043df4709Smrg    if(pPriv->VIP!=NULL){
136143df4709Smrg        RADEONVIP_reset(pScrn,pPriv);
136243df4709Smrg        }
136343df4709Smrg
136443df4709Smrg    if(pPriv->theatre != NULL) {
136543df4709Smrg        xf86_InitTheatre(pPriv->theatre);
136643df4709Smrg/*      xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); */
136743df4709Smrg        }
136843df4709Smrg
136943df4709Smrg    if(pPriv->i2c != NULL){
137043df4709Smrg        RADEONResetI2C(pScrn, pPriv);
137143df4709Smrg        }
137243df4709Smrg}
137343df4709Smrg
137443df4709Smrgstatic void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
137543df4709Smrg{
137643df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
137743df4709Smrg    RADEONPLLPtr  pll = &(info->pll);
137843df4709Smrg    TheatrePtr t;
137943df4709Smrg
138043df4709Smrg    uint8_t a;
138143df4709Smrg    int i;
138243df4709Smrg
138343df4709Smrg    pPriv->theatre = NULL;
138443df4709Smrg
138543df4709Smrg    if(!info->MM_TABLE_valid &&
138643df4709Smrg       !((info->RageTheatreCrystal>=0) &&
138743df4709Smrg           (info->RageTheatreTunerPort>=0) && (info->RageTheatreCompositePort>=0) &&
138843df4709Smrg           (info->RageTheatreSVideoPort>=0)))
138943df4709Smrg    {
139043df4709Smrg       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no multimedia table present, disabling Rage Theatre.\n");
139143df4709Smrg       return;
139243df4709Smrg    }
139343df4709Smrg
139443df4709Smrg    /* Go and find Rage Theatre, if it exists */
139543df4709Smrg
139643df4709Smrg    if (info->IsMobility)
139743df4709Smrg	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n");
139843df4709Smrg    else
139943df4709Smrg	pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
140043df4709Smrg
140143df4709Smrg    if(pPriv->theatre==NULL)return;
140243df4709Smrg
140343df4709Smrg    /* just a matter of convenience */
140443df4709Smrg    t=pPriv->theatre;
140543df4709Smrg
140643df4709Smrg    t->video_decoder_type=info->video_decoder_type;
140743df4709Smrg
140843df4709Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type is 0x%04x (BIOS value) versus 0x%04x (current PLL setting)\n",
140943df4709Smrg         t->video_decoder_type, pll->xclk);
141043df4709Smrg
141143df4709Smrg    if(info->MM_TABLE_valid){
141243df4709Smrg         for(i=0;i<5;i++){
141343df4709Smrg                a=info->MM_TABLE.input[i];
141443df4709Smrg
141543df4709Smrg                switch(a & 0x3){
141643df4709Smrg                        case 1:
141743df4709Smrg                                t->wTunerConnector=i;
141843df4709Smrg                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tuner is on port %d\n",i);
141943df4709Smrg                                break;
142043df4709Smrg                        case 2:  if(a & 0x4){
142143df4709Smrg                                   t->wComp0Connector=RT_COMP2;
142243df4709Smrg                                   } else {
142343df4709Smrg                                   t->wComp0Connector=RT_COMP1;
142443df4709Smrg                                   }
142543df4709Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector);
142643df4709Smrg                                  break;
142743df4709Smrg                        case 3:  if(a & 0x4){
142843df4709Smrg                                   t->wSVideo0Connector=RT_YCR_COMP4;
142943df4709Smrg                                   } else {
143043df4709Smrg                                   t->wSVideo0Connector=RT_YCF_COMP4;
143143df4709Smrg                                   }
143243df4709Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector);
143343df4709Smrg                                   break;
143443df4709Smrg                        default:
143543df4709Smrg                                break;
143643df4709Smrg                        }
143743df4709Smrg                }
143843df4709Smrg        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n",
143943df4709Smrg    	     (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
144043df4709Smrg
144143df4709Smrg         }
144243df4709Smrg
144343df4709Smrg    if(info->RageTheatreTunerPort>=0)t->wTunerConnector=info->RageTheatreTunerPort;
144443df4709Smrg    if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort;
144543df4709Smrg    if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort;
144643df4709Smrg
144743df4709Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n",
144843df4709Smrg    	(unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
144943df4709Smrg
145043df4709Smrg    switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){
145143df4709Smrg                case 2700:
145243df4709Smrg                        t->video_decoder_type=RT_FREF_2700;
145343df4709Smrg                        break;
145443df4709Smrg                case 2950:
145543df4709Smrg                        t->video_decoder_type=RT_FREF_2950;
145643df4709Smrg                        break;
145743df4709Smrg                default:
145843df4709Smrg                        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
145943df4709Smrg                                "Unsupported reference clock frequency, Rage Theatre disabled\n");
146043df4709Smrg                        t->theatre_num=-1;
146143df4709Smrg			free(pPriv->theatre);
146243df4709Smrg			pPriv->theatre = NULL;
146343df4709Smrg			return;
146443df4709Smrg                }
146543df4709Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type used: 0x%04x\n", t->video_decoder_type);
146643df4709Smrg}
146743df4709Smrg
146843df4709Smrgstatic XF86VideoAdaptorPtr
146943df4709SmrgRADEONAllocAdaptor(ScrnInfoPtr pScrn)
147043df4709Smrg{
147143df4709Smrg    XF86VideoAdaptorPtr adapt;
147243df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
147343df4709Smrg    RADEONPortPrivPtr pPriv;
147443df4709Smrg    uint32_t dot_clock;
147543df4709Smrg    int ecp;
147643df4709Smrg
147743df4709Smrg    if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
147843df4709Smrg	return NULL;
147943df4709Smrg
148043df4709Smrg    if(!(pPriv = calloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion))))
148143df4709Smrg    {
148243df4709Smrg	free(adapt);
148343df4709Smrg	return NULL;
148443df4709Smrg    }
148543df4709Smrg
148643df4709Smrg    adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
148743df4709Smrg    adapt->pPortPrivates[0].ptr = (pointer)pPriv;
148843df4709Smrg
148943df4709Smrg    pPriv->colorKey = info->videoKey;
149043df4709Smrg    pPriv->doubleBuffer = TRUE;
149143df4709Smrg    pPriv->videoStatus = 0;
149243df4709Smrg    pPriv->brightness = 0;
149343df4709Smrg    pPriv->transform_index = 0;
149443df4709Smrg    pPriv->saturation = 0;
149543df4709Smrg    pPriv->contrast = 0;
149643df4709Smrg    pPriv->red_intensity = 0;
149743df4709Smrg    pPriv->green_intensity = 0;
149843df4709Smrg    pPriv->blue_intensity = 0;
149943df4709Smrg    pPriv->hue = 0;
150043df4709Smrg    pPriv->currentBuffer = 0;
150143df4709Smrg    pPriv->autopaint_colorkey = TRUE;
150243df4709Smrg    pPriv->gamma = 1000;
150343df4709Smrg    pPriv->desired_crtc = NULL;
150443df4709Smrg
150543df4709Smrg    pPriv->ov_alpha = 255;
150643df4709Smrg    pPriv->gr_alpha = 255;
150743df4709Smrg    pPriv->alpha_mode = 0;
150843df4709Smrg
150943df4709Smrg       /* TV-in stuff */
151043df4709Smrg    pPriv->video_stream_active = FALSE;
151143df4709Smrg    pPriv->encoding = 4;
151243df4709Smrg    pPriv->frequency = 1000;
151343df4709Smrg    pPriv->volume = -1000;
151443df4709Smrg    pPriv->mute = TRUE;
151543df4709Smrg    pPriv->v = 0;
151643df4709Smrg    pPriv->overlay_deinterlacing_method = METHOD_BOB;
151743df4709Smrg    pPriv->capture_vbi_data = 0;
151843df4709Smrg    pPriv->dec_brightness = 0;
151943df4709Smrg    pPriv->dec_saturation = 0;
152043df4709Smrg    pPriv->dec_contrast = 0;
152143df4709Smrg    pPriv->dec_hue = 0;
152243df4709Smrg
152343df4709Smrg
152443df4709Smrg    /*
152543df4709Smrg     * Unlike older Mach64 chips, RADEON has only two ECP settings:
152643df4709Smrg     * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
152743df4709Smrg     * for higher clocks, sure makes life nicer
152843df4709Smrg     */
152943df4709Smrg    dot_clock = info->ModeReg->dot_clock_freq;
153043df4709Smrg
153143df4709Smrg    if (dot_clock < 17500)
153243df4709Smrg        info->ecp_div = 0;
153343df4709Smrg    else
153443df4709Smrg        info->ecp_div = 1;
153543df4709Smrg    ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
153643df4709Smrg
153743df4709Smrg    if (info->IsIGP) {
153843df4709Smrg        /* Force the overlay clock on for integrated chips
153943df4709Smrg	 */
154043df4709Smrg        ecp |= (1<<18);
154143df4709Smrg    }
154243df4709Smrg
154343df4709Smrg    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp);
154443df4709Smrg
154543df4709Smrg
154643df4709Smrg    /* Decide on tuner type */
154743df4709Smrg    if((info->tunerType<0) && (info->MM_TABLE_valid)) {
154843df4709Smrg        pPriv->tuner_type = info->MM_TABLE.tuner_type;
154943df4709Smrg    	} else
155043df4709Smrg        pPriv->tuner_type = info->tunerType;
155143df4709Smrg
155243df4709Smrg    /* Initialize I2C bus */
155343df4709Smrg    RADEONInitI2C(pScrn, pPriv);
155443df4709Smrg    if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
155543df4709Smrg
155643df4709Smrg
155743df4709Smrg    #if 0  /* this is just here for easy debugging - normally off */
155843df4709Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n");
155943df4709Smrg    for(i=0;i<255;i+=2)
156043df4709Smrg        if(RADEONProbeAddress(pPriv->i2c, i))
156143df4709Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "     found device at address 0x%02x\n", i);
156243df4709Smrg    #endif
156343df4709Smrg
156443df4709Smrg    /* resetting the VIP bus causes problems with some mobility chips.
156543df4709Smrg     * we don't support video in on any mobility chips at the moment anyway
156643df4709Smrg     */
156743df4709Smrg    /* Initialize VIP bus */
156843df4709Smrg    if (!info->IsMobility)
156943df4709Smrg	RADEONVIP_init(pScrn, pPriv);
157043df4709Smrg
157143df4709Smrg    info->adaptor = adapt;
157243df4709Smrg    info->xv_max_width = 2047;
157343df4709Smrg    info->xv_max_height = 2047;
157443df4709Smrg
157543df4709Smrg	if(!xf86LoadSubModule(pScrn,"theatre_detect"))
157643df4709Smrg	{
157743df4709Smrg		xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n");
157843df4709Smrg		goto skip_theatre;
157943df4709Smrg    }
158043df4709Smrg	RADEONSetupTheatre(pScrn, pPriv);
158143df4709Smrg
158243df4709Smrg	/*
158343df4709Smrg	 * Now load the correspondind theatre chip based on what has been detected.
158443df4709Smrg	 */
158543df4709Smrg	if (pPriv->theatre)
158643df4709Smrg	{
158743df4709Smrg		xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Going to load the corresponding theatre module\n");
158843df4709Smrg		switch (pPriv->theatre->theatre_id)
158943df4709Smrg		{
159043df4709Smrg			case RT100_ATI_ID:
159143df4709Smrg			{
159243df4709Smrg				if(!xf86LoadSubModule(pScrn,"theatre"))
159343df4709Smrg				{
159443df4709Smrg					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
159543df4709Smrg					free(pPriv->theatre);
159643df4709Smrg					goto skip_theatre;
159743df4709Smrg				}
159843df4709Smrg				break;
159943df4709Smrg			}
160043df4709Smrg			case RT200_ATI_ID:
160143df4709Smrg			{
160243df4709Smrg				if(!xf86LoadSubModule(pScrn,"theatre200"))
160343df4709Smrg				{
160443df4709Smrg					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
160543df4709Smrg					free(pPriv->theatre);
160643df4709Smrg					goto skip_theatre;
160743df4709Smrg				}
160843df4709Smrg				pPriv->theatre->microc_path = info->RageTheatreMicrocPath;
160943df4709Smrg				pPriv->theatre->microc_type = info->RageTheatreMicrocType;
161043df4709Smrg				break;
161143df4709Smrg			}
161243df4709Smrg			default:
161343df4709Smrg			{
161443df4709Smrg				xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unknown Theatre chip\n");
161543df4709Smrg				free(pPriv->theatre);
161643df4709Smrg				goto skip_theatre;
161743df4709Smrg			}
161843df4709Smrg		}
1619209ff23fSmrg	}
162043df4709Smrg
162143df4709Smrg	if(pPriv->theatre!=NULL)
162243df4709Smrg	{
162343df4709Smrg		xf86_InitTheatre(pPriv->theatre);
162443df4709Smrg		if(pPriv->theatre->mode == MODE_UNINITIALIZED)
162543df4709Smrg		{
162643df4709Smrg			free(pPriv->theatre);
162743df4709Smrg			pPriv->theatre = NULL;
162843df4709Smrg			xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Rage Theatre disabled\n");
162943df4709Smrg			/* Here the modules must be unloaded */
163043df4709Smrg			goto skip_theatre;
163143df4709Smrg		}
1632209ff23fSmrg	}
163343df4709Smrg
163443df4709Smrg    if(pPriv->theatre!=NULL){
163543df4709Smrg        xf86_ResetTheatreRegsForNoTVout(pPriv->theatre);
163643df4709Smrg        xf86_RT_SetTint(pPriv->theatre, pPriv->dec_hue);
163743df4709Smrg        xf86_RT_SetSaturation(pPriv->theatre, pPriv->dec_saturation);
163843df4709Smrg        xf86_RT_SetSharpness(pPriv->theatre, RT_NORM_SHARPNESS);
163943df4709Smrg        xf86_RT_SetContrast(pPriv->theatre, pPriv->dec_contrast);
164043df4709Smrg        xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
1641209ff23fSmrg
164243df4709Smrg        RADEON_RT_SetEncoding(pScrn, pPriv);
164343df4709Smrg	}
164443df4709Smrg
164543df4709Smrgskip_theatre:
164643df4709Smrg
164743df4709Smrg    return adapt;
164843df4709Smrg}
164943df4709Smrg
165043df4709Smrgstatic XF86VideoAdaptorPtr
165143df4709SmrgRADEONSetupImageVideo(ScreenPtr pScreen)
165243df4709Smrg{
165343df4709Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
165443df4709Smrg    RADEONPortPrivPtr pPriv;
165543df4709Smrg    XF86VideoAdaptorPtr adapt;
165643df4709Smrg
165743df4709Smrg    if(!(adapt = RADEONAllocAdaptor(pScrn)))
165843df4709Smrg	return NULL;
165943df4709Smrg
166043df4709Smrg    adapt->type = XvWindowMask | XvInputMask | XvImageMask;
166143df4709Smrg    adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
166243df4709Smrg    adapt->name = "ATI Radeon Video Overlay";
166343df4709Smrg    adapt->nEncodings = 1;
166443df4709Smrg    adapt->pEncodings = &DummyEncoding;
166543df4709Smrg    adapt->nFormats = NUM_FORMATS;
166643df4709Smrg    adapt->pFormats = Formats;
166743df4709Smrg    adapt->nPorts = 1;
166843df4709Smrg    adapt->nAttributes = NUM_ATTRIBUTES;
166943df4709Smrg    adapt->pAttributes = Attributes;
167043df4709Smrg    adapt->nImages = NUM_IMAGES;
167143df4709Smrg    adapt->pImages = Images;
167243df4709Smrg    adapt->PutVideo = NULL;
167343df4709Smrg    adapt->PutStill = NULL;
167443df4709Smrg    adapt->GetVideo = NULL;
167543df4709Smrg    adapt->GetStill = NULL;
167643df4709Smrg    adapt->StopVideo = RADEONStopVideo;
167743df4709Smrg    adapt->SetPortAttribute = RADEONSetPortAttribute;
167843df4709Smrg    adapt->GetPortAttribute = RADEONGetPortAttribute;
167943df4709Smrg    adapt->QueryBestSize = RADEONQueryBestSize;
168043df4709Smrg    adapt->PutImage = RADEONPutImage;
168143df4709Smrg    adapt->QueryImageAttributes = RADEONQueryImageAttributes;
168243df4709Smrg
168343df4709Smrg    pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr);
168443df4709Smrg    REGION_NULL(pScreen, &(pPriv->clip));
168543df4709Smrg
168643df4709Smrg    pPriv->textured = FALSE;
168743df4709Smrg
168843df4709Smrg    if(pPriv->theatre != NULL) {
168943df4709Smrg	/* video decoder is present, extend capabilities */
169043df4709Smrg       adapt->nEncodings = 13;
169143df4709Smrg       adapt->pEncodings = InputVideoEncodings;
169243df4709Smrg       adapt->type |= XvVideoMask;
169343df4709Smrg       adapt->nAttributes = NUM_DEC_ATTRIBUTES;
169443df4709Smrg       adapt->PutVideo = RADEONPutVideo;
169543df4709Smrg    }
169643df4709Smrg
169743df4709Smrg    RADEONResetVideo(pScrn);
169843df4709Smrg
169943df4709Smrg    return adapt;
170043df4709Smrg}
170143df4709Smrg
170243df4709Smrgvoid
170343df4709SmrgRADEONFreeVideoMemory(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
170443df4709Smrg{
170543df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
170643df4709Smrg
170743df4709Smrg    if (pPriv->video_memory != NULL) {
170843df4709Smrg	radeon_legacy_free_memory(pScrn, pPriv->video_memory);
170943df4709Smrg	pPriv->video_memory = NULL;
171043df4709Smrg
171143df4709Smrg	if (info->cs && pPriv->textured) {
171243df4709Smrg	    pPriv->src_bo[0] = NULL;
171343df4709Smrg	    radeon_legacy_free_memory(pScrn, pPriv->src_bo[1]);
171443df4709Smrg	    pPriv->src_bo[1] = NULL;
171543df4709Smrg	}
171643df4709Smrg    }
171743df4709Smrg}
171843df4709Smrg
171943df4709Smrgvoid
172043df4709SmrgRADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
172143df4709Smrg{
172243df4709Smrg  RADEONInfoPtr info = RADEONPTR(pScrn);
172343df4709Smrg  unsigned char *RADEONMMIO = info->MMIO;
172443df4709Smrg  RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
172543df4709Smrg
172643df4709Smrg  if (pPriv->textured) {
172743df4709Smrg      if (cleanup) {
172843df4709Smrg	  RADEONFreeVideoMemory(pScrn, pPriv);
172943df4709Smrg      }
173043df4709Smrg      return;
173143df4709Smrg  }
173243df4709Smrg
173343df4709Smrg  REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
173443df4709Smrg
173543df4709Smrg  if(cleanup) {
173643df4709Smrg     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
173743df4709Smrg	RADEONWaitForFifo(pScrn, 2);
173843df4709Smrg	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
173943df4709Smrg     }
174043df4709Smrg     if(pPriv->video_stream_active){
174143df4709Smrg        RADEONWaitForFifo(pScrn, 2);
174243df4709Smrg        OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
174343df4709Smrg        OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
174443df4709Smrg        RADEONResetVideo(pScrn);
174543df4709Smrg        pPriv->video_stream_active = FALSE;
174643df4709Smrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
174743df4709Smrg		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE);
174843df4709Smrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
174943df4709Smrg     }
175043df4709Smrg     RADEONFreeVideoMemory(pScrn, pPriv);
175143df4709Smrg     pPriv->videoStatus = 0;
175243df4709Smrg  } else {
175343df4709Smrg     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
175443df4709Smrg	pPriv->videoStatus |= OFF_TIMER;
175543df4709Smrg	pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
175643df4709Smrg     }
175743df4709Smrg  }
175843df4709Smrg}
175943df4709Smrg
176043df4709Smrgint
176143df4709SmrgRADEONSetPortAttribute(ScrnInfoPtr  pScrn,
176243df4709Smrg		       Atom	    attribute,
176343df4709Smrg		       INT32	    value,
176443df4709Smrg		       pointer	    data)
176543df4709Smrg{
176643df4709Smrg    RADEONInfoPtr	info = RADEONPTR(pScrn);
176743df4709Smrg    RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
176843df4709Smrg    Bool		setTransform = FALSE;
176943df4709Smrg    Bool		setAlpha = FALSE;
177043df4709Smrg    unsigned char *RADEONMMIO = info->MMIO;
177143df4709Smrg
177243df4709Smrg    RADEON_SYNC(info, pScrn);
177343df4709Smrg
177443df4709Smrg    if(attribute == xvAutopaintColorkey)
177543df4709Smrg    {
177643df4709Smrg	pPriv->autopaint_colorkey = ClipValue (value, 0, 1);
177743df4709Smrg    }
177843df4709Smrg    else if(attribute == xvSetDefaults)
177943df4709Smrg    {
178043df4709Smrg	pPriv->autopaint_colorkey = TRUE;
178143df4709Smrg	pPriv->brightness = 0;
178243df4709Smrg	pPriv->saturation = 0;
178343df4709Smrg	pPriv->contrast = 0;
178443df4709Smrg	pPriv->hue = 0;
178543df4709Smrg	pPriv->red_intensity = 0;
178643df4709Smrg	pPriv->green_intensity = 0;
178743df4709Smrg	pPriv->blue_intensity = 0;
178843df4709Smrg	pPriv->gamma = 1000;
178943df4709Smrg	pPriv->transform_index = 0;
179043df4709Smrg	pPriv->doubleBuffer = FALSE;
179143df4709Smrg	pPriv->ov_alpha = 255;
179243df4709Smrg	pPriv->gr_alpha = 255;
179343df4709Smrg	pPriv->alpha_mode = 0;
179443df4709Smrg
179543df4709Smrg        /* It is simpler to call itself */
179643df4709Smrg        RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data);
179743df4709Smrg        RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data);
179843df4709Smrg        RADEONSetPortAttribute(pScrn, xvDecContrast,   0, data);
179943df4709Smrg        RADEONSetPortAttribute(pScrn, xvDecHue,   0, data);
180043df4709Smrg
180143df4709Smrg        RADEONSetPortAttribute(pScrn, xvVolume,   -1000, data);
180243df4709Smrg        RADEONSetPortAttribute(pScrn, xvMute,   1, data);
180343df4709Smrg        RADEONSetPortAttribute(pScrn, xvSAP,   0, data);
180443df4709Smrg        RADEONSetPortAttribute(pScrn, xvDoubleBuffer,   1, data);
180543df4709Smrg
180643df4709Smrg	setTransform = TRUE;
180743df4709Smrg	setAlpha = TRUE;
180843df4709Smrg    }
180943df4709Smrg    else if(attribute == xvBrightness)
181043df4709Smrg    {
181143df4709Smrg	pPriv->brightness = ClipValue (value, -1000, 1000);
181243df4709Smrg	setTransform = TRUE;
181343df4709Smrg    }
181443df4709Smrg    else if((attribute == xvSaturation) || (attribute == xvColor))
181543df4709Smrg    {
181643df4709Smrg	pPriv->saturation = ClipValue (value, -1000, 1000);
181743df4709Smrg	setTransform = TRUE;
181843df4709Smrg    }
181943df4709Smrg    else if(attribute == xvContrast)
182043df4709Smrg    {
182143df4709Smrg	pPriv->contrast = ClipValue (value, -1000, 1000);
182243df4709Smrg	setTransform = TRUE;
182343df4709Smrg    }
182443df4709Smrg    else if(attribute == xvHue)
182543df4709Smrg    {
182643df4709Smrg	pPriv->hue = ClipValue (value, -1000, 1000);
182743df4709Smrg	setTransform = TRUE;
182843df4709Smrg    }
182943df4709Smrg    else if(attribute == xvRedIntensity)
183043df4709Smrg    {
183143df4709Smrg	pPriv->red_intensity = ClipValue (value, -1000, 1000);
183243df4709Smrg	setTransform = TRUE;
183343df4709Smrg    }
183443df4709Smrg    else if(attribute == xvGreenIntensity)
183543df4709Smrg    {
183643df4709Smrg	pPriv->green_intensity = ClipValue (value, -1000, 1000);
183743df4709Smrg	setTransform = TRUE;
183843df4709Smrg    }
183943df4709Smrg    else if(attribute == xvBlueIntensity)
184043df4709Smrg    {
184143df4709Smrg	pPriv->blue_intensity = ClipValue (value, -1000, 1000);
184243df4709Smrg	setTransform = TRUE;
184343df4709Smrg    }
184443df4709Smrg    else if(attribute == xvGamma)
184543df4709Smrg    {
184643df4709Smrg	pPriv->gamma = ClipValue (value, 100, 10000);
184743df4709Smrg	setTransform = TRUE;
184843df4709Smrg    }
184943df4709Smrg    else if(attribute == xvColorspace)
185043df4709Smrg    {
185143df4709Smrg	pPriv->transform_index = ClipValue (value, 0, 1);
185243df4709Smrg	setTransform = TRUE;
185343df4709Smrg    }
185443df4709Smrg    else if(attribute == xvDoubleBuffer)
185543df4709Smrg    {
185643df4709Smrg	pPriv->doubleBuffer = ClipValue (value, 0, 1);
185743df4709Smrg    }
185843df4709Smrg    else if(attribute == xvColorKey)
185943df4709Smrg    {
186043df4709Smrg	pPriv->colorKey = value;
186143df4709Smrg	RADEONSetColorKey (pScrn, pPriv->colorKey);
186243df4709Smrg	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
186343df4709Smrg    }
186443df4709Smrg    else if(attribute == xvCRTC)
186543df4709Smrg    {
186643df4709Smrg	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
186743df4709Smrg	if ((value < -1) || (value > xf86_config->num_crtc))
186843df4709Smrg	    return BadValue;
186943df4709Smrg	if (value < 0)
187043df4709Smrg	    pPriv->desired_crtc = NULL;
187143df4709Smrg	else
187243df4709Smrg	    pPriv->desired_crtc = xf86_config->crtc[value];
187343df4709Smrg    }
187443df4709Smrg    else if(attribute == xvOvAlpha)
187543df4709Smrg    {
187643df4709Smrg	pPriv->ov_alpha = ClipValue (value, 0, 255);
187743df4709Smrg	setAlpha = TRUE;
187843df4709Smrg    }
187943df4709Smrg    else if(attribute == xvGrAlpha)
188043df4709Smrg    {
188143df4709Smrg	pPriv->gr_alpha = ClipValue (value, 0, 255);
188243df4709Smrg	setAlpha = TRUE;
188343df4709Smrg    }
188443df4709Smrg    else if(attribute == xvAlphaMode)
188543df4709Smrg    {
188643df4709Smrg	pPriv->alpha_mode = ClipValue (value, 0, 1);
188743df4709Smrg	setAlpha = TRUE;
188843df4709Smrg    }
188943df4709Smrg    else if(attribute == xvDecBrightness)
189043df4709Smrg    {
189143df4709Smrg        pPriv->dec_brightness = value;
189243df4709Smrg        if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
189343df4709Smrg    }
189443df4709Smrg    else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
189543df4709Smrg    {
189643df4709Smrg        if(value<-1000)value = -1000;
189743df4709Smrg        if(value>1000)value = 1000;
189843df4709Smrg        pPriv->dec_saturation = value;
189943df4709Smrg        if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value);
190043df4709Smrg    }
190143df4709Smrg    else if(attribute == xvDecContrast)
190243df4709Smrg    {
190343df4709Smrg        pPriv->dec_contrast = value;
190443df4709Smrg        if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value);
190543df4709Smrg    }
190643df4709Smrg    else if(attribute == xvDecHue)
190743df4709Smrg    {
190843df4709Smrg        pPriv->dec_hue = value;
190943df4709Smrg        if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value);
191043df4709Smrg    }
191143df4709Smrg    else if(attribute == xvEncoding)
191243df4709Smrg    {
191343df4709Smrg        pPriv->encoding = value;
191443df4709Smrg        if(pPriv->video_stream_active)
191543df4709Smrg        {
191643df4709Smrg           if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);
191743df4709Smrg           if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
191843df4709Smrg           if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
191943df4709Smrg	   if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
192043df4709Smrg           if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
192143df4709Smrg        /* put more here to actually change it */
192243df4709Smrg        }
192343df4709Smrg   }
192443df4709Smrg   else if(attribute == xvFrequency)
192543df4709Smrg   {
192643df4709Smrg        pPriv->frequency = value;
192743df4709Smrg        /* mute volume if it was not muted before */
192843df4709Smrg        if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
192943df4709Smrg		if((pPriv->uda1380!=NULL)&& !pPriv->mute)xf86_uda1380_mute(pPriv->uda1380, TRUE);
193043df4709Smrg        if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value);
193143df4709Smrg/*        if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);  */
193243df4709Smrg        if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck))
193343df4709Smrg                xf86_InitMSP3430(pPriv->msp3430);
193443df4709Smrg        if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume));
193543df4709Smrg		if((pPriv->uda1380 != NULL)&& !pPriv->mute) xf86_uda1380_setvolume(pPriv->uda1380, pPriv->volume);
193643df4709Smrg   }
193743df4709Smrg   else if(attribute == xvMute)
193843df4709Smrg   {
193943df4709Smrg        pPriv->mute = value;
194043df4709Smrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
194143df4709Smrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
194243df4709Smrg		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, pPriv->mute);
194343df4709Smrg   }
194443df4709Smrg   else if(attribute == xvSAP)
194543df4709Smrg   {
194643df4709Smrg        pPriv->sap_channel = value;
194743df4709Smrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3);
194843df4709Smrg   }
194943df4709Smrg   else if(attribute == xvVolume)
195043df4709Smrg   {
195143df4709Smrg        if(value<-1000)value = -1000;
195243df4709Smrg        if(value>1000)value = 1000;
195343df4709Smrg        pPriv->volume = value;
195443df4709Smrg        pPriv->mute = FALSE;
195543df4709Smrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value));
195643df4709Smrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
195743df4709Smrg		if(pPriv->uda1380 != NULL) xf86_uda1380_setvolume(pPriv->uda1380, value);
195843df4709Smrg   }
195943df4709Smrg   else if(attribute == xvOverlayDeinterlacingMethod)
196043df4709Smrg   {
196143df4709Smrg        if(value<0)value = 0;
196243df4709Smrg        if(value>2)value = 2;
196343df4709Smrg        pPriv->overlay_deinterlacing_method = value;
196443df4709Smrg        switch(pPriv->overlay_deinterlacing_method){
196543df4709Smrg                case METHOD_BOB:
196643df4709Smrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
196743df4709Smrg                        break;
196843df4709Smrg                case METHOD_SINGLE:
196943df4709Smrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
197043df4709Smrg                        break;
197143df4709Smrg                case METHOD_WEAVE:
197243df4709Smrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0);
197343df4709Smrg                        break;
197443df4709Smrg                default:
197543df4709Smrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
197643df4709Smrg                }
197743df4709Smrg   }
197843df4709Smrg   else if(attribute == xvDumpStatus)
197943df4709Smrg   {
198043df4709Smrg  	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n",
198143df4709Smrg		pScrn->currentMode->Flags,
198243df4709Smrg		pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" ,
198343df4709Smrg		pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : ""
198443df4709Smrg		);
198543df4709Smrg	if(pPriv->tda9885 != NULL){
198643df4709Smrg		xf86_tda9885_getstatus(pPriv->tda9885);
198743df4709Smrg		xf86_tda9885_dumpstatus(pPriv->tda9885);
198843df4709Smrg		}
198943df4709Smrg	if(pPriv->fi1236!=NULL){
199043df4709Smrg		xf86_fi1236_dump_status(pPriv->fi1236);
199143df4709Smrg		}
199243df4709Smrg   }
199343df4709Smrg   else if(attribute == xvAdjustment)
199443df4709Smrg   {
199543df4709Smrg  	pPriv->adjustment=value;
199643df4709Smrg        xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n",
199743df4709Smrg		   (unsigned)pPriv->adjustment);
199843df4709Smrg  	if(pPriv->tda9885!=0){
199943df4709Smrg		pPriv->tda9885->top_adjustment=value;
200043df4709Smrg		RADEON_TDA9885_SetEncoding(pPriv);
200143df4709Smrg		}
200243df4709Smrg   }
200343df4709Smrg   else
200443df4709Smrg	return BadMatch;
200543df4709Smrg
200643df4709Smrg    if (setTransform)
200743df4709Smrg    {
200843df4709Smrg	RADEONSetTransform(pScrn,
200943df4709Smrg			   RTFBrightness(pPriv->brightness),
201043df4709Smrg			   RTFContrast(pPriv->contrast),
201143df4709Smrg			   RTFSaturation(pPriv->saturation),
201243df4709Smrg			   RTFHue(pPriv->hue),
201343df4709Smrg			   RTFIntensity(pPriv->red_intensity),
201443df4709Smrg			   RTFIntensity(pPriv->green_intensity),
201543df4709Smrg			   RTFIntensity(pPriv->blue_intensity),
201643df4709Smrg			   pPriv->transform_index,
201743df4709Smrg			   pPriv->gamma);
201843df4709Smrg    }
201943df4709Smrg
202043df4709Smrg    if (setAlpha)
202143df4709Smrg    {
202243df4709Smrg	RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode);
202343df4709Smrg    }
202443df4709Smrg
202543df4709Smrg    return Success;
202643df4709Smrg}
202743df4709Smrg
202843df4709Smrgint
202943df4709SmrgRADEONGetPortAttribute(ScrnInfoPtr  pScrn,
203043df4709Smrg		       Atom	    attribute,
203143df4709Smrg		       INT32	    *value,
203243df4709Smrg		       pointer	    data)
203343df4709Smrg{
203443df4709Smrg    RADEONInfoPtr	info = RADEONPTR(pScrn);
203543df4709Smrg    RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
203643df4709Smrg
203743df4709Smrg    if (info->accelOn) RADEON_SYNC(info, pScrn);
203843df4709Smrg
203943df4709Smrg    if(attribute == xvAutopaintColorkey)
204043df4709Smrg	*value = pPriv->autopaint_colorkey;
204143df4709Smrg    else if(attribute == xvBrightness)
204243df4709Smrg	*value = pPriv->brightness;
204343df4709Smrg    else if((attribute == xvSaturation) || (attribute == xvColor))
204443df4709Smrg	*value = pPriv->saturation;
204543df4709Smrg    else if(attribute == xvContrast)
204643df4709Smrg	*value = pPriv->contrast;
204743df4709Smrg    else if(attribute == xvHue)
204843df4709Smrg	*value = pPriv->hue;
204943df4709Smrg    else if(attribute == xvRedIntensity)
205043df4709Smrg	*value = pPriv->red_intensity;
205143df4709Smrg    else if(attribute == xvGreenIntensity)
205243df4709Smrg	*value = pPriv->green_intensity;
205343df4709Smrg    else if(attribute == xvBlueIntensity)
205443df4709Smrg	*value = pPriv->blue_intensity;
205543df4709Smrg    else if(attribute == xvGamma)
205643df4709Smrg	*value = pPriv->gamma;
205743df4709Smrg    else if(attribute == xvColorspace)
205843df4709Smrg	*value = pPriv->transform_index;
205943df4709Smrg    else if(attribute == xvDoubleBuffer)
206043df4709Smrg	*value = pPriv->doubleBuffer ? 1 : 0;
206143df4709Smrg    else if(attribute == xvColorKey)
206243df4709Smrg	*value = pPriv->colorKey;
206343df4709Smrg    else if(attribute == xvCRTC) {
206443df4709Smrg	int		c;
206543df4709Smrg	xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
206643df4709Smrg	for (c = 0; c < xf86_config->num_crtc; c++)
206743df4709Smrg	    if (xf86_config->crtc[c] == pPriv->desired_crtc)
206843df4709Smrg		break;
206943df4709Smrg	if (c == xf86_config->num_crtc)
207043df4709Smrg	    c = -1;
207143df4709Smrg	*value = c;
207243df4709Smrg    }
207343df4709Smrg    else if(attribute == xvOvAlpha)
207443df4709Smrg	*value = pPriv->ov_alpha;
207543df4709Smrg    else if(attribute == xvGrAlpha)
207643df4709Smrg	*value = pPriv->gr_alpha;
207743df4709Smrg    else if(attribute == xvAlphaMode)
207843df4709Smrg	*value = pPriv->alpha_mode;
207943df4709Smrg    else if(attribute == xvDecBrightness)
208043df4709Smrg        *value = pPriv->dec_brightness;
208143df4709Smrg    else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
208243df4709Smrg        *value = pPriv->dec_saturation;
208343df4709Smrg    else if(attribute == xvDecContrast)
208443df4709Smrg        *value = pPriv->dec_contrast;
208543df4709Smrg    else if(attribute == xvDecHue)
208643df4709Smrg        *value = pPriv->dec_hue;
208743df4709Smrg    else if(attribute == xvEncoding)
208843df4709Smrg        *value = pPriv->encoding;
208943df4709Smrg    else if(attribute == xvFrequency)
209043df4709Smrg        *value = pPriv->frequency;
209143df4709Smrg    else
209243df4709Smrg    if(attribute == xvTunerStatus) {
209343df4709Smrg        if(pPriv->fi1236==NULL){
209443df4709Smrg                *value=TUNER_OFF;
209543df4709Smrg                } else
209643df4709Smrg                {
209743df4709Smrg                *value = xf86_TUNER_get_afc_hint(pPriv->fi1236);
209843df4709Smrg                }
209943df4709Smrg       }
210043df4709Smrg    else if(attribute == xvMute)
210143df4709Smrg        *value = pPriv->mute;
210243df4709Smrg    else if(attribute == xvSAP)
210343df4709Smrg        *value = pPriv->sap_channel;
210443df4709Smrg    else if(attribute == xvVolume)
210543df4709Smrg        *value = pPriv->volume;
210643df4709Smrg    else if(attribute == xvOverlayDeinterlacingMethod)
210743df4709Smrg        *value = pPriv->overlay_deinterlacing_method;
210843df4709Smrg    else if(attribute == xvDeviceID)
210943df4709Smrg        *value = pPriv->device_id;
211043df4709Smrg    else if(attribute == xvLocationID)
211143df4709Smrg        *value = pPriv->location_id;
211243df4709Smrg    else if(attribute == xvInstanceID)
211343df4709Smrg        *value = pPriv->instance_id;
211443df4709Smrg    else if(attribute == xvAdjustment)
211543df4709Smrg  	*value = pPriv->adjustment;
211643df4709Smrg    else
211743df4709Smrg	return BadMatch;
211843df4709Smrg
211943df4709Smrg    return Success;
212043df4709Smrg}
212143df4709Smrg
212243df4709Smrgvoid
212343df4709SmrgRADEONQueryBestSize(
212443df4709Smrg  ScrnInfoPtr pScrn,
212543df4709Smrg  Bool motion,
212643df4709Smrg  short vid_w, short vid_h,
212743df4709Smrg  short drw_w, short drw_h,
212843df4709Smrg  unsigned int *p_w, unsigned int *p_h,
212943df4709Smrg  pointer data
213043df4709Smrg){
213143df4709Smrg    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
213243df4709Smrg
213343df4709Smrg    if (!pPriv->textured) {
213443df4709Smrg	if (vid_w > (drw_w << 4))
213543df4709Smrg	    drw_w = vid_w >> 4;
213643df4709Smrg	if (vid_h > (drw_h << 4))
213743df4709Smrg	    drw_h = vid_h >> 4;
213843df4709Smrg    }
213943df4709Smrg
214043df4709Smrg  *p_w = drw_w;
214143df4709Smrg  *p_h = drw_h;
214243df4709Smrg}
214343df4709Smrg
214443df4709Smrgstatic struct {
214543df4709Smrg	double range;
214643df4709Smrg	signed char coeff[5][4];
214743df4709Smrg	} TapCoeffs[]=
214843df4709Smrg	{
214943df4709Smrg        {0.25, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13,   13,    3}, }},
215043df4709Smrg        {0.26, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215143df4709Smrg        {0.27, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215243df4709Smrg        {0.28, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215343df4709Smrg        {0.29, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215443df4709Smrg        {0.30, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215543df4709Smrg        {0.31, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215643df4709Smrg        {0.32, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215743df4709Smrg        {0.33, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215843df4709Smrg        {0.34, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
215943df4709Smrg        {0.35, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216043df4709Smrg        {0.36, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216143df4709Smrg        {0.37, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216243df4709Smrg        {0.38, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216343df4709Smrg        {0.39, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216443df4709Smrg        {0.40, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216543df4709Smrg        {0.41, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216643df4709Smrg        {0.42, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216743df4709Smrg        {0.43, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216843df4709Smrg        {0.44, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
216943df4709Smrg        {0.45, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
217043df4709Smrg        {0.46, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
217143df4709Smrg        {0.47, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
217243df4709Smrg        {0.48, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
217343df4709Smrg        {0.49, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
217443df4709Smrg        {0.50, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
217543df4709Smrg        {0.51, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 2,   14, 14,  2}, }},
217643df4709Smrg        {0.52, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
217743df4709Smrg        {0.53, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
217843df4709Smrg        {0.54, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
217943df4709Smrg        {0.55, {{ 7,    18,  7,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 1,   15, 15,  1}, }},
218043df4709Smrg        {0.56, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218143df4709Smrg        {0.57, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218243df4709Smrg        {0.58, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218343df4709Smrg        {0.59, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218443df4709Smrg        {0.60, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218543df4709Smrg        {0.61, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218643df4709Smrg        {0.62, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218743df4709Smrg        {0.63, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218843df4709Smrg        {0.64, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
218943df4709Smrg        {0.65, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
219043df4709Smrg        {0.66, {{ 7,    18,  8, -1}, { 6,   18, 10, -2}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
219143df4709Smrg        {0.67, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   18, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
219243df4709Smrg        {0.68, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
219343df4709Smrg        {0.69, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
219443df4709Smrg        {0.70, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
219543df4709Smrg        {0.71, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
219643df4709Smrg        {0.72, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
219743df4709Smrg        {0.73, {{ 7,    20,  7, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
219843df4709Smrg        {0.74, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
219943df4709Smrg        {0.75, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
220043df4709Smrg        {0.76, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
220143df4709Smrg        {0.77, {{ 6,    22,  6, -2}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
220243df4709Smrg        {0.78, {{ 6,    21,  6, -1}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
220343df4709Smrg        {0.79, {{ 5,    23,  5, -1}, { 3,   22,  9, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
220443df4709Smrg        {0.80, {{ 5,    23,  5, -1}, { 3,   23,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
220543df4709Smrg        {0.81, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
220643df4709Smrg        {0.82, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-3,   19, 19, -3}, }},
220743df4709Smrg        {0.83, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
220843df4709Smrg        {0.84, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
220943df4709Smrg        {0.85, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
221043df4709Smrg        {0.86, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
221143df4709Smrg        {0.87, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
221243df4709Smrg        {0.88, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
221343df4709Smrg        {0.89, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
221443df4709Smrg        {0.90, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
221543df4709Smrg        {0.91, {{ 3,    26,  3,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
221643df4709Smrg        {0.92, {{ 2,    28,  2,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
221743df4709Smrg        {0.93, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
221843df4709Smrg        {0.94, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
221943df4709Smrg        {0.95, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
222043df4709Smrg        {0.96, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
222143df4709Smrg        {0.97, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
222243df4709Smrg        {0.98, {{ 1,    30,  1,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
222343df4709Smrg        {0.99, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }},
222443df4709Smrg        {1.00, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }}
222543df4709Smrg    };
222643df4709Smrg
222743df4709Smrgvoid
222843df4709SmrgRADEONCopyData(
222943df4709Smrg  ScrnInfoPtr pScrn,
223043df4709Smrg  unsigned char *src,
223143df4709Smrg  unsigned char *dst,
223243df4709Smrg  unsigned int srcPitch,
223343df4709Smrg  unsigned int dstPitch,
223443df4709Smrg  unsigned int h,
223543df4709Smrg  unsigned int w,
223643df4709Smrg  unsigned int bpp
223743df4709Smrg){
223843df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
223943df4709Smrg
224043df4709Smrg    /* Get the byte-swapping right for big endian systems */
224143df4709Smrg    if ( bpp == 2 ) {
224243df4709Smrg	w *= 2;
224343df4709Smrg	bpp = 1;
224443df4709Smrg    }
224543df4709Smrg
224643df4709Smrg#ifdef XF86DRI
224743df4709Smrg
224843df4709Smrg    if ( info->directRenderingEnabled && info->DMAForXv )
224943df4709Smrg    {
225043df4709Smrg	uint8_t *buf;
225143df4709Smrg	uint32_t bufPitch, dstPitchOff;
225243df4709Smrg	int x, y;
225343df4709Smrg	unsigned int hpass;
225443df4709Smrg
225543df4709Smrg	RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y );
225643df4709Smrg
225743df4709Smrg	while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch,
225843df4709Smrg					   x, &y, &h, &hpass )) )
225943df4709Smrg	{
226043df4709Smrg	    RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch,
226143df4709Smrg					srcPitch );
226243df4709Smrg	    src += hpass * srcPitch;
226343df4709Smrg	}
226443df4709Smrg
226543df4709Smrg	FLUSH_RING();
226643df4709Smrg
226743df4709Smrg	return;
226843df4709Smrg    }
226943df4709Smrg    else
227043df4709Smrg#endif /* XF86DRI */
227143df4709Smrg    {
227243df4709Smrg	int swap = RADEON_HOST_DATA_SWAP_NONE;
227343df4709Smrg
227443df4709Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
227543df4709Smrg	if (info->kms_enabled) {
227643df4709Smrg	    switch(bpp) {
227743df4709Smrg	    case 2:
227843df4709Smrg		swap = RADEON_HOST_DATA_SWAP_16BIT;
227943df4709Smrg		break;
228043df4709Smrg	    case 4:
228143df4709Smrg		swap = RADEON_HOST_DATA_SWAP_32BIT;
228243df4709Smrg		break;
228343df4709Smrg	    }
228443df4709Smrg	} else {
228543df4709Smrg	    switch (pScrn->bitsPerPixel) {
228643df4709Smrg	    case 16:
228743df4709Smrg		swap = RADEON_HOST_DATA_SWAP_16BIT;
228843df4709Smrg		break;
228943df4709Smrg	    case 32:
229043df4709Smrg		swap = RADEON_HOST_DATA_SWAP_32BIT;
229143df4709Smrg		break;
229243df4709Smrg	    }
229343df4709Smrg	}
229443df4709Smrg#endif
229543df4709Smrg
229643df4709Smrg	w *= bpp;
229743df4709Smrg
229843df4709Smrg	if (dstPitch == w && dstPitch == srcPitch)
229943df4709Smrg	    RADEONCopySwap(dst, src, h * dstPitch, swap);
230043df4709Smrg	else {
230143df4709Smrg	    while (h--) {
230243df4709Smrg		RADEONCopySwap(dst, src, w, swap);
230343df4709Smrg		src += srcPitch;
230443df4709Smrg		dst += dstPitch;
230543df4709Smrg	    }
230643df4709Smrg	}
230743df4709Smrg    }
230843df4709Smrg}
230943df4709Smrg
231043df4709Smrgstatic void
231143df4709SmrgRADEONCopyRGB24Data(
231243df4709Smrg  ScrnInfoPtr pScrn,
231343df4709Smrg  unsigned char *src,
231443df4709Smrg  unsigned char *dst,
231543df4709Smrg  unsigned int srcPitch,
231643df4709Smrg  unsigned int dstPitch,
231743df4709Smrg  unsigned int h,
231843df4709Smrg  unsigned int w
231943df4709Smrg){
232043df4709Smrg    uint32_t *dptr;
232143df4709Smrg    uint8_t *sptr;
232243df4709Smrg    int i,j;
232343df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
232443df4709Smrg#ifdef XF86DRI
232543df4709Smrg
232643df4709Smrg    if ( info->directRenderingEnabled && info->DMAForXv )
232743df4709Smrg    {
232843df4709Smrg	uint32_t bufPitch, dstPitchOff;
232943df4709Smrg	int x, y;
233043df4709Smrg	unsigned int hpass;
233143df4709Smrg
233243df4709Smrg	RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y );
233343df4709Smrg
233443df4709Smrg	while ( (dptr = ( uint32_t* )RADEONHostDataBlit( pScrn, 4, w, dstPitchOff,
233543df4709Smrg						       &bufPitch, x, &y, &h,
233643df4709Smrg						       &hpass )) )
233743df4709Smrg	{
233843df4709Smrg	    for( j = 0; j < hpass; j++ )
233943df4709Smrg	    {
234043df4709Smrg		sptr = src;
234143df4709Smrg
234243df4709Smrg		for ( i = 0 ; i < w; i++, sptr += 3 )
234343df4709Smrg		{
234443df4709Smrg		    dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0];
234543df4709Smrg		}
234643df4709Smrg
234743df4709Smrg		src += srcPitch;
234843df4709Smrg		dptr += bufPitch / 4;
234943df4709Smrg	    }
235043df4709Smrg	}
235143df4709Smrg
235243df4709Smrg	FLUSH_RING();
235343df4709Smrg
235443df4709Smrg	return;
235543df4709Smrg    }
235643df4709Smrg    else
235743df4709Smrg#endif /* XF86DRI */
235843df4709Smrg    {
235943df4709Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
236043df4709Smrg	unsigned char *RADEONMMIO = info->MMIO;
236143df4709Smrg
236243df4709Smrg	if (!info->kms_enabled)
236343df4709Smrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
236443df4709Smrg		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
236543df4709Smrg#endif
236643df4709Smrg
236743df4709Smrg	for (j = 0; j < h; j++) {
236843df4709Smrg	    dptr = (uint32_t *)(dst + j * dstPitch);
236943df4709Smrg	    sptr = src + j * srcPitch;
237043df4709Smrg
237143df4709Smrg	    for (i = 0; i < w; i++, sptr += 3) {
237243df4709Smrg		dptr[i] = cpu_to_le32((sptr[2] << 16) | (sptr[1] << 8) | sptr[0]);
237343df4709Smrg	    }
237443df4709Smrg	}
237543df4709Smrg
237643df4709Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
237743df4709Smrg	if (!info->kms_enabled) {
237843df4709Smrg	    /* restore byte swapping */
237943df4709Smrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
238043df4709Smrg	}
238143df4709Smrg#endif
238243df4709Smrg    }
238343df4709Smrg}
238443df4709Smrg
238543df4709Smrg
238643df4709Smrg#ifdef XF86DRI
238743df4709Smrgstatic void RADEON_420_422(
238843df4709Smrg    unsigned int *d,
238943df4709Smrg    unsigned char *s1,
239043df4709Smrg    unsigned char *s2,
239143df4709Smrg    unsigned char *s3,
239243df4709Smrg    unsigned int n
239343df4709Smrg)
239443df4709Smrg{
239543df4709Smrg    while ( n ) {
239643df4709Smrg	*(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
239743df4709Smrg	s1+=2; s2++; s3++;
239843df4709Smrg	n--;
239943df4709Smrg    }
240043df4709Smrg}
240143df4709Smrg#endif
240243df4709Smrg
240343df4709Smrgvoid
240443df4709SmrgRADEONCopyMungedData(
240543df4709Smrg   ScrnInfoPtr pScrn,
240643df4709Smrg   unsigned char *src1,
240743df4709Smrg   unsigned char *src2,
240843df4709Smrg   unsigned char *src3,
240943df4709Smrg   unsigned char *dst1,
241043df4709Smrg   unsigned int srcPitch,
241143df4709Smrg   unsigned int srcPitch2,
241243df4709Smrg   unsigned int dstPitch,
241343df4709Smrg   unsigned int h,
241443df4709Smrg   unsigned int w
241543df4709Smrg){
241643df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
241743df4709Smrg#ifdef XF86DRI
241843df4709Smrg
241943df4709Smrg    if ( info->directRenderingEnabled && info->DMAForXv )
242043df4709Smrg    {
242143df4709Smrg	uint8_t *buf;
242243df4709Smrg	uint32_t y = 0, bufPitch, dstPitchOff;
242343df4709Smrg	int blitX, blitY;
242443df4709Smrg	unsigned int hpass;
242543df4709Smrg
242643df4709Smrg	/* XXX Fix endian flip on R300 */
242743df4709Smrg
242843df4709Smrg	RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY );
242943df4709Smrg
243043df4709Smrg	while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch,
243143df4709Smrg					   blitX, &blitY, &h, &hpass )) )
243243df4709Smrg	{
243343df4709Smrg	    while ( hpass-- )
243443df4709Smrg	    {
243543df4709Smrg		RADEON_420_422( (unsigned int *) buf, src1, src2, src3,
243643df4709Smrg				bufPitch / 4 );
243743df4709Smrg		src1 += srcPitch;
243843df4709Smrg		if ( y & 1 )
243943df4709Smrg		{
244043df4709Smrg		    src2 += srcPitch2;
244143df4709Smrg		    src3 += srcPitch2;
244243df4709Smrg		}
244343df4709Smrg		buf += bufPitch;
244443df4709Smrg		y++;
244543df4709Smrg	    }
244643df4709Smrg	}
244743df4709Smrg
244843df4709Smrg	FLUSH_RING();
244943df4709Smrg    }
245043df4709Smrg    else
245143df4709Smrg#endif /* XF86DRI */
245243df4709Smrg    {
245343df4709Smrg	uint32_t *dst;
245443df4709Smrg	uint8_t *s1, *s2, *s3;
245543df4709Smrg	int i, j;
245643df4709Smrg
245743df4709Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
245843df4709Smrg	unsigned char *RADEONMMIO = info->MMIO;
245943df4709Smrg
246043df4709Smrg	if (!info->kms_enabled)
246143df4709Smrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
246243df4709Smrg		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
246343df4709Smrg#endif
246443df4709Smrg
246543df4709Smrg	w /= 2;
246643df4709Smrg
246743df4709Smrg	for( j = 0; j < h; j++ )
246843df4709Smrg	{
246943df4709Smrg	    dst = (pointer)dst1;
247043df4709Smrg	    s1 = src1;  s2 = src2;  s3 = src3;
247143df4709Smrg	    i = w;
247243df4709Smrg	    while( i > 4 )
247343df4709Smrg	    {
247443df4709Smrg		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
247543df4709Smrg		dst[1] = cpu_to_le32(s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24));
247643df4709Smrg		dst[2] = cpu_to_le32(s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24));
247743df4709Smrg		dst[3] = cpu_to_le32(s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24));
247843df4709Smrg		dst += 4; s2 += 4; s3 += 4; s1 += 8;
247943df4709Smrg		i -= 4;
248043df4709Smrg	    }
248143df4709Smrg	    while( i-- )
248243df4709Smrg	    {
248343df4709Smrg		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
248443df4709Smrg		dst++; s2++; s3++;
248543df4709Smrg		s1 += 2;
248643df4709Smrg	    }
248743df4709Smrg
248843df4709Smrg	    dst1 += dstPitch;
248943df4709Smrg	    src1 += srcPitch;
249043df4709Smrg	    if( j & 1 )
249143df4709Smrg	    {
249243df4709Smrg		src2 += srcPitch2;
249343df4709Smrg		src3 += srcPitch2;
249443df4709Smrg	    }
249543df4709Smrg	}
249643df4709Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
249743df4709Smrg	if (!info->kms_enabled) {
249843df4709Smrg	    /* restore byte swapping */
249943df4709Smrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
250043df4709Smrg	}
250143df4709Smrg#endif
250243df4709Smrg    }
250343df4709Smrg}
250443df4709Smrg
250543df4709Smrgstatic void
250643df4709SmrgRADEONDisplayVideo(
250743df4709Smrg    ScrnInfoPtr pScrn,
250843df4709Smrg    xf86CrtcPtr crtc,
250943df4709Smrg    RADEONPortPrivPtr pPriv,
251043df4709Smrg    int id,
251143df4709Smrg    int base_offset,
251243df4709Smrg    int offset1, int offset2,
251343df4709Smrg    int offset3, int offset4,
251443df4709Smrg    int offset5, int offset6,
251543df4709Smrg    short width, short height,
251643df4709Smrg    int pitch,
251743df4709Smrg    int left, int right, int top,
251843df4709Smrg    BoxPtr dstBox,
251943df4709Smrg    short src_w, short src_h,
252043df4709Smrg    short drw_w, short drw_h,
252143df4709Smrg    int deinterlacing_method
252243df4709Smrg){
252343df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
252443df4709Smrg    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
252543df4709Smrg    unsigned char *RADEONMMIO = info->MMIO;
252643df4709Smrg    uint32_t v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp;
252743df4709Smrg    double h_inc_d;
252843df4709Smrg    int p1_h_accum_init, p23_h_accum_init;
252943df4709Smrg    int p1_v_accum_init, p23_v_accum_init;
253043df4709Smrg    int p23_blank_lines;
253143df4709Smrg    int ecp_div;
253243df4709Smrg    int v_inc_shift;
253343df4709Smrg    int y_mult;
253443df4709Smrg    int x_off;
253543df4709Smrg    int y_off;
253643df4709Smrg    uint32_t scaler_src;
253743df4709Smrg    uint32_t dot_clock;
253843df4709Smrg    int is_rgb;
253943df4709Smrg    int is_planar;
254043df4709Smrg    int i;
254143df4709Smrg    uint32_t scale_cntl;
254243df4709Smrg    double dsr;
254343df4709Smrg    int tap_set;
254443df4709Smrg    int predownscale=0;
254543df4709Smrg    int src_w_d;
254643df4709Smrg    int leftuv = 0;
254743df4709Smrg    DisplayModePtr mode;
254843df4709Smrg    RADEONOutputPrivatePtr radeon_output;
254943df4709Smrg    xf86OutputPtr output;
255043df4709Smrg    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
255143df4709Smrg
255243df4709Smrg    is_rgb=0; is_planar=0;
255343df4709Smrg    switch(id){
255443df4709Smrg        case FOURCC_I420:
255543df4709Smrg        case FOURCC_YV12:
255643df4709Smrg            is_planar=1;
255743df4709Smrg            break;
255843df4709Smrg        case FOURCC_RGBA32:
255943df4709Smrg        case FOURCC_RGB24:
256043df4709Smrg        case FOURCC_RGBT16:
256143df4709Smrg        case FOURCC_RGB16:
256243df4709Smrg            is_rgb=1;
256343df4709Smrg            break;
256443df4709Smrg        default:
256543df4709Smrg	    break;
256643df4709Smrg    }
256743df4709Smrg
256843df4709Smrg    /* Here we need to find ecp_div again, as the user may have switched resolutions
256943df4709Smrg       but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to
257043df4709Smrg       workarounds for chip erratas */
257143df4709Smrg
257243df4709Smrg    /* Figure out which head we are on for dot clock */
257343df4709Smrg    if (radeon_crtc->crtc_id == 1)
257443df4709Smrg        dot_clock = info->ModeReg->dot_clock_freq_2;
257543df4709Smrg    else
257643df4709Smrg        dot_clock = info->ModeReg->dot_clock_freq;
257743df4709Smrg
257843df4709Smrg    if (dot_clock < 17500)
257943df4709Smrg        ecp_div = 0;
258043df4709Smrg    else
258143df4709Smrg	ecp_div = 1;
258243df4709Smrg
258343df4709Smrg    if (ecp_div != info->ecp_div) {
258443df4709Smrg	info->ecp_div = ecp_div;
258543df4709Smrg	OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
258643df4709Smrg	   (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
258743df4709Smrg    }
258843df4709Smrg
258943df4709Smrg    /* I suspect we may need a usleep after writing to the PLL.  if you play a video too soon
259043df4709Smrg       after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
259143df4709Smrg       on the right edge video output.
259243df4709Smrg       Is this still the case? Might have been chips which need the errata,
259343df4709Smrg       there is now plenty of usleep after INPLL/OUTPLL for those...*/
259443df4709Smrg
259543df4709Smrg    v_inc_shift = 20;
259643df4709Smrg    y_mult = 1;
259743df4709Smrg
259843df4709Smrg    mode = &crtc->mode;
259943df4709Smrg
260043df4709Smrg    if (mode->Flags & V_INTERLACE)
260143df4709Smrg	v_inc_shift++;
260243df4709Smrg    if (mode->Flags & V_DBLSCAN) {
260343df4709Smrg	v_inc_shift--;
260443df4709Smrg	y_mult = 2;
260543df4709Smrg    }
260643df4709Smrg
260743df4709Smrg    v_inc = (src_h << v_inc_shift) / drw_h;
260843df4709Smrg
260943df4709Smrg    for (i = 0; i < xf86_config->num_output; i++) {
261043df4709Smrg	output = xf86_config->output[i];
261143df4709Smrg	if (output->crtc == crtc) {
261243df4709Smrg	    radeon_output = output->driver_private;
261343df4709Smrg	    if (radeon_output->Flags & RADEON_USE_RMX)
261443df4709Smrg		v_inc = ((src_h * mode->CrtcVDisplay /
261543df4709Smrg			  radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h;
261643df4709Smrg	    break;
261743df4709Smrg	}
261843df4709Smrg    }
261943df4709Smrg
262043df4709Smrg    h_inc = (1 << (12 + ecp_div));
262143df4709Smrg
262243df4709Smrg    step_by_y = 1;
262343df4709Smrg    step_by_uv = step_by_y;
262443df4709Smrg
262543df4709Smrg    src_w_d = src_w;
262643df4709Smrg#if 0
262743df4709Smrg    /* XXX this does not appear to work */
262843df4709Smrg    /* if the source width was larger than what would fit in overlay scaler increase step_by values */
262943df4709Smrg    i=src_w;
263043df4709Smrg    while(i>info->overlay_scaler_buffer_width){
263143df4709Smrg	step_by_y++;
263243df4709Smrg	step_by_uv++;
263343df4709Smrg	h_inc >>=1;
263443df4709Smrg	i=i/2;
263543df4709Smrg	}
263643df4709Smrg#else
263743df4709Smrg    /* predownscale instead (yes this hurts quality) - will only work for widths up
263843df4709Smrg       to 2 times the overlay_scaler_buffer_width, should be enough */
263943df4709Smrg    if (src_w_d > info->overlay_scaler_buffer_width) {
264043df4709Smrg	src_w_d /= 2; /* odd widths? */
264143df4709Smrg	predownscale = 1;
264243df4709Smrg    }
264343df4709Smrg#endif
264443df4709Smrg
264543df4709Smrg    h_inc_d = src_w_d;
264643df4709Smrg    h_inc_d = h_inc_d/drw_w;
264743df4709Smrg    /* we could do a tad better  - but why
264843df4709Smrg       bother when this concerns downscaling and the code is so much more
264943df4709Smrg       hairy */
265043df4709Smrg    while(h_inc*h_inc_d >= (2 << 12)) {
265143df4709Smrg        if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){
265243df4709Smrg                step_by_uv = step_by_y+1;
265343df4709Smrg                break;
265443df4709Smrg                }
265543df4709Smrg        step_by_y++;
265643df4709Smrg        step_by_uv = step_by_y;
265743df4709Smrg        h_inc >>= 1;
265843df4709Smrg    }
265943df4709Smrg
266043df4709Smrg    h_inc_uv = h_inc>>(step_by_uv-step_by_y);
266143df4709Smrg    h_inc = h_inc * h_inc_d;
266243df4709Smrg    h_inc_uv = h_inc_uv * h_inc_d;
266343df4709Smrg    /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit
266443df4709Smrg       in the buffer for 2 tap filtering */
266543df4709Smrg    /* the only place it is documented in is in ATI source code */
266643df4709Smrg    /* we need twice as much space for 4 tap filtering.. */
266743df4709Smrg    /* under special circumstances turn on 4 tap filtering */
266843df4709Smrg    /* disable this code for now as it has a DISASTROUS effect on image quality when upscaling
266943df4709Smrg       at least on rv250 (only as long as the drw_w*2 <=... requirement is still met of course) */
267043df4709Smrg#if 0
267143df4709Smrg    if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12))
267243df4709Smrg       && (deinterlacing_method!=METHOD_WEAVE)
267343df4709Smrg       && (drw_w*2 <= info->overlay_scaler_buffer_width)){
267443df4709Smrg        step_by_y=0;
267543df4709Smrg        step_by_uv=1;
267643df4709Smrg        h_inc_uv = h_inc;
267743df4709Smrg        }
267843df4709Smrg#endif
267943df4709Smrg
268043df4709Smrg    /* Make the overlay base address as close to the buffers as possible to
268143df4709Smrg     * prevent the buffer offsets from exceeding the hardware limit of 128 MB.
268243df4709Smrg     * The base address must be aligned to a multiple of 4 MB.
268343df4709Smrg     */
26841cad17e5Schristos    base_offset = ((info->fbLocation + base_offset) & (~0U << 22)) -
268543df4709Smrg	info->fbLocation;
268643df4709Smrg
268743df4709Smrg    offset1 -= base_offset;
268843df4709Smrg    offset2 -= base_offset;
268943df4709Smrg    offset3 -= base_offset;
269043df4709Smrg    offset4 -= base_offset;
269143df4709Smrg    offset5 -= base_offset;
269243df4709Smrg    offset6 -= base_offset;
269343df4709Smrg
269443df4709Smrg    /* keep everything in 16.16 */
269543df4709Smrg
269643df4709Smrg    if (is_planar) {
269743df4709Smrg	offset1 += ((left >> 16) & ~15);
269843df4709Smrg	offset2 += ((left >> 16) & ~31) >> 1;
269943df4709Smrg	offset3 += ((left >> 16) & ~31) >> 1;
270043df4709Smrg	offset4 += ((left >> 16) & ~15);
270143df4709Smrg	offset5 += ((left >> 16) & ~31) >> 1;
270243df4709Smrg	offset6 += ((left >> 16) & ~31) >> 1;
270343df4709Smrg	offset2 |= RADEON_VIF_BUF0_PITCH_SEL;
270443df4709Smrg	offset3 |= RADEON_VIF_BUF0_PITCH_SEL;
270543df4709Smrg	offset5 |= RADEON_VIF_BUF0_PITCH_SEL;
270643df4709Smrg	offset6 |= RADEON_VIF_BUF0_PITCH_SEL;
270743df4709Smrg    }
270843df4709Smrg    else {
270943df4709Smrg	/* is this really correct for non-2-byte formats? */
271043df4709Smrg	offset1 += ((left >> 16) & ~7) << 1;
271143df4709Smrg	offset2 += ((left >> 16) & ~7) << 1;
271243df4709Smrg	offset3 += ((left >> 16) & ~7) << 1;
271343df4709Smrg	offset4 += ((left >> 16) & ~7) << 1;
271443df4709Smrg	offset5 += ((left >> 16) & ~7) << 1;
271543df4709Smrg	offset6 += ((left >> 16) & ~7) << 1;
271643df4709Smrg    }
271743df4709Smrg
271843df4709Smrg    tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
271943df4709Smrg    p1_h_accum_init = ((tmp <<  4) & 0x000f8000) |
272043df4709Smrg		      ((tmp << 12) & 0xf0000000);
272143df4709Smrg
272243df4709Smrg    tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2);
272343df4709Smrg    p23_h_accum_init = ((tmp <<  4) & 0x000f8000) |
272443df4709Smrg		       ((tmp << 12) & 0x70000000);
272543df4709Smrg
272643df4709Smrg    tmp = (top & 0x0000ffff) + 0x00018000;
272743df4709Smrg    p1_v_accum_init = ((tmp << 4) & 0x03ff8000) |
272843df4709Smrg    	(((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01);
272943df4709Smrg
273043df4709Smrg    if (is_planar) {
273143df4709Smrg	p23_v_accum_init = ((tmp << 4) & 0x03ff8000) |
273243df4709Smrg	    ((deinterlacing_method != METHOD_WEAVE) ? 0x03 : 0x01);
273343df4709Smrg	p23_blank_lines = (((src_h >> 1) - 1) << 16);
273443df4709Smrg    }
273543df4709Smrg    else {
273643df4709Smrg	p23_v_accum_init = 0;
273743df4709Smrg	p23_blank_lines = 0;
273843df4709Smrg    }
273943df4709Smrg
274043df4709Smrg    if (is_planar) {
274143df4709Smrg	leftuv = ((left >> 16) >> 1) & 15;
274243df4709Smrg	left = (left >> 16) & 15;
274343df4709Smrg    }
274443df4709Smrg    else {
274543df4709Smrg	left = (left >> 16) & 7;
274643df4709Smrg	if (!is_rgb)
274743df4709Smrg	    leftuv = left >> 1;
274843df4709Smrg    }
274943df4709Smrg
275043df4709Smrg    RADEONWaitForFifo(pScrn, 2);
275143df4709Smrg    OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK);
275243df4709Smrg    if (info->accelOn) RADEON_SYNC(info, pScrn);
275343df4709Smrg    while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
275443df4709Smrg
275543df4709Smrg    RADEONWaitForFifo(pScrn, 10);
275643df4709Smrg    OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16));
275743df4709Smrg    OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) |
275843df4709Smrg	predownscale << 4 | predownscale << 12);
275943df4709Smrg
276043df4709Smrg    x_off = 8;
276143df4709Smrg    y_off = 0;
276243df4709Smrg
276343df4709Smrg    if (IS_R300_VARIANT ||
276443df4709Smrg        (info->ChipFamily == CHIP_FAMILY_R200))
276543df4709Smrg	x_off = 0;
276643df4709Smrg
276743df4709Smrg    /* needed to make the overlay work on crtc1 in leftof and above modes */
276843df4709Smrg    /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */
276943df4709Smrg    /*
277043df4709Smrg    if (srel == radeonLeftOf) {
277143df4709Smrg	x_off -= mode->CrtcHDisplay;
277243df4709Smrg    }
277343df4709Smrg    if (srel == radeonAbove) {
277443df4709Smrg	y_off -= mode->CrtcVDisplay;
277543df4709Smrg    }
277643df4709Smrg    */
277743df4709Smrg
277843df4709Smrg    /* Put the hardware overlay on CRTC2:
277943df4709Smrg     *
278043df4709Smrg     * Since one hardware overlay can not be displayed on two heads
278143df4709Smrg     * at the same time, we might need to consider using software
278243df4709Smrg     * rendering for the second head.
278343df4709Smrg     */
278443df4709Smrg
278543df4709Smrg    if (radeon_crtc->crtc_id == 1) {
278643df4709Smrg        x_off = 0;
278743df4709Smrg        OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
278843df4709Smrg                                      ((dstBox->y1*y_mult) << 16)));
278943df4709Smrg        OUTREG(RADEON_OV1_Y_X_END,   ((dstBox->x2 + x_off) |
279043df4709Smrg                                      ((dstBox->y2*y_mult) << 16)));
279143df4709Smrg        scaler_src = RADEON_SCALER_CRTC_SEL;
279243df4709Smrg    } else {
279343df4709Smrg	OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) |
279443df4709Smrg				      (((dstBox->y1*y_mult) + y_off) << 16)));
279543df4709Smrg	OUTREG(RADEON_OV0_Y_X_END,   ((dstBox->x2 + x_off) |
279643df4709Smrg				      (((dstBox->y2*y_mult) + y_off) << 16)));
279743df4709Smrg	scaler_src = 0;
279843df4709Smrg    }
279943df4709Smrg
280043df4709Smrg    /* program the tap coefficients for better downscaling quality.
280143df4709Smrg       Could do slightly better by using hardcoded coefficients for one axis
280243df4709Smrg       in case only the other axis is downscaled (see RADEON_OV0_FILTER_CNTL) */
280343df4709Smrg    dsr=(double)(1<<0xC)/h_inc;
280443df4709Smrg    if(dsr<0.25)dsr=0.25;
280543df4709Smrg    if(dsr>1.0)dsr=1.0;
280643df4709Smrg    tap_set=(int)((dsr-0.25)*100);
280743df4709Smrg    for(i=0;i<5;i++){
280843df4709Smrg	    OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) |
280943df4709Smrg	    	((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) |
281043df4709Smrg	    	((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) |
281143df4709Smrg	    	((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24));
281243df4709Smrg		}
281343df4709Smrg
281443df4709Smrg    RADEONWaitForFifo(pScrn, 11);
281543df4709Smrg    OUTREG(RADEON_OV0_V_INC, v_inc);
281643df4709Smrg    OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));
281743df4709Smrg    OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | p23_blank_lines);
281843df4709Smrg    OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch);
281943df4709Smrg    OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch);
282043df4709Smrg    OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16));
282143df4709Smrg    if (!is_rgb)
282243df4709Smrg	src_w >>= 1;
282343df4709Smrg    OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
282443df4709Smrg    OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
282543df4709Smrg    if (info->ModeReg->ov0_base_addr != (info->fbLocation + base_offset)) {
282643df4709Smrg	ErrorF("Changing OV0_BASE_ADDR from 0x%08x to 0x%08x\n",
282743df4709Smrg	       info->ModeReg->ov0_base_addr, (uint32_t)info->fbLocation + base_offset);
282843df4709Smrg	info->ModeReg->ov0_base_addr = info->fbLocation + base_offset;
282943df4709Smrg	OUTREG(RADEON_OV0_BASE_ADDR, info->ModeReg->ov0_base_addr);
283043df4709Smrg    }
283143df4709Smrg    OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1);
283243df4709Smrg    OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2);
283343df4709Smrg    OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3);
283443df4709Smrg
283543df4709Smrg    RADEONWaitForFifo(pScrn, 9);
283643df4709Smrg    OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4);
283743df4709Smrg    OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset5);
283843df4709Smrg    OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset6);
283943df4709Smrg    OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
284043df4709Smrg    OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
284143df4709Smrg    OUTREG(RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init);
284243df4709Smrg    OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
284343df4709Smrg
284443df4709Smrg   scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER
284543df4709Smrg        | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16) | scaler_src;
284643df4709Smrg   switch(id){
284743df4709Smrg        case FOURCC_UYVY:
284843df4709Smrg		scale_cntl |= RADEON_SCALER_SOURCE_YVYU422;
284943df4709Smrg		break;
285043df4709Smrg        case FOURCC_RGB24:
285143df4709Smrg        case FOURCC_RGBA32:
285243df4709Smrg		scale_cntl |= RADEON_SCALER_SOURCE_32BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
285343df4709Smrg		break;
285443df4709Smrg        case FOURCC_RGB16:
285543df4709Smrg		scale_cntl |= RADEON_SCALER_SOURCE_16BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
285643df4709Smrg		break;
285743df4709Smrg        case FOURCC_RGBT16:
285843df4709Smrg		scale_cntl |= RADEON_SCALER_SOURCE_15BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
285943df4709Smrg		break;
286043df4709Smrg        case FOURCC_YV12:
286143df4709Smrg        case FOURCC_I420:
286243df4709Smrg		scale_cntl |= RADEON_SCALER_SOURCE_YUV12;
286343df4709Smrg		break;
286443df4709Smrg        case FOURCC_YUY2:
286543df4709Smrg        default:
286643df4709Smrg		scale_cntl |= RADEON_SCALER_SOURCE_VYUY422
286743df4709Smrg			| ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0);
286843df4709Smrg		break;
286943df4709Smrg    }
287043df4709Smrg
287143df4709Smrg    if (info->ChipFamily < CHIP_FAMILY_R200) {
287243df4709Smrg	scale_cntl &= ~RADEON_SCALER_GAMMA_SEL_MASK;
287343df4709Smrg	scale_cntl |= ((RADEONTranslateUserGamma(pPriv->gamma)) << 5);
287443df4709Smrg    }
287543df4709Smrg
287643df4709Smrg    OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl);
287743df4709Smrg    OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
287843df4709Smrg}
287943df4709Smrg
288043df4709Smrg
288143df4709Smrgstatic void
288243df4709SmrgRADEONFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes)
288343df4709Smrg{
288443df4709Smrg#if HAVE_XV_DRAWABLE_HELPER
288543df4709Smrg    xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes);
288643df4709Smrg#else
288743df4709Smrg    xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes);
288843df4709Smrg#endif
288943df4709Smrg}
289043df4709Smrg
289143df4709Smrg
289243df4709Smrgstatic int
289343df4709SmrgRADEONPutImage(
289443df4709Smrg  ScrnInfoPtr pScrn,
289543df4709Smrg  short src_x, short src_y,
289643df4709Smrg  short drw_x, short drw_y,
289743df4709Smrg  short src_w, short src_h,
289843df4709Smrg  short drw_w, short drw_h,
289943df4709Smrg  int id, unsigned char* buf,
290043df4709Smrg  short width, short height,
290143df4709Smrg  Bool Sync,
290243df4709Smrg  RegionPtr clipBoxes, pointer data,
290343df4709Smrg  DrawablePtr pDraw
290443df4709Smrg){
290543df4709Smrg   RADEONInfoPtr info = RADEONPTR(pScrn);
290643df4709Smrg   RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
290743df4709Smrg   INT32 xa, xb, ya, yb;
290843df4709Smrg   unsigned char *dst_start;
290943df4709Smrg   int new_size, offset, s2offset, s3offset;
291043df4709Smrg   int srcPitch, srcPitch2, dstPitch;
291143df4709Smrg   int d2line, d3line;
291243df4709Smrg   int top, left, npixels, nlines, bpp;
291343df4709Smrg   int idconv = id;
291443df4709Smrg   BoxRec dstBox;
291543df4709Smrg   uint32_t tmp;
291643df4709Smrg   xf86CrtcPtr crtc;
291743df4709Smrg
291843df4709Smrg   /*
291943df4709Smrg    * s2offset, s3offset - byte offsets into U and V plane of the
292043df4709Smrg    *                      source where copying starts.  Y plane is
292143df4709Smrg    *                      done by editing "buf".
292243df4709Smrg    *
292343df4709Smrg    * offset - byte offset to the first line of the destination.
292443df4709Smrg    *
292543df4709Smrg    * dst_start - byte address to the first displayed pel.
292643df4709Smrg    *
292743df4709Smrg    */
292843df4709Smrg
292943df4709Smrg   /* make the compiler happy */
293043df4709Smrg   s2offset = s3offset = srcPitch2 = 0;
293143df4709Smrg   d2line = d3line = 0;
293243df4709Smrg
293343df4709Smrg   if(src_w > (drw_w << 4))
293443df4709Smrg	drw_w = src_w >> 4;
293543df4709Smrg   if(src_h > (drw_h << 4))
293643df4709Smrg	drw_h = src_h >> 4;
293743df4709Smrg
293843df4709Smrg   /* Clip */
293943df4709Smrg   xa = src_x;
294043df4709Smrg   xb = src_x + src_w;
294143df4709Smrg   ya = src_y;
294243df4709Smrg   yb = src_y + src_h;
294343df4709Smrg
294443df4709Smrg   dstBox.x1 = drw_x;
294543df4709Smrg   dstBox.x2 = drw_x + drw_w;
294643df4709Smrg   dstBox.y1 = drw_y;
294743df4709Smrg   dstBox.y2 = drw_y + drw_h;
294843df4709Smrg
294943df4709Smrg   if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
295043df4709Smrg			       &dstBox, &xa, &xb, &ya, &yb,
295143df4709Smrg			       clipBoxes, width, height))
295243df4709Smrg       return Success;
295343df4709Smrg
295443df4709Smrg   if (!crtc) {
295543df4709Smrg       if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
295643df4709Smrg	   unsigned char *RADEONMMIO = info->MMIO;
295743df4709Smrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
295843df4709Smrg	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
295943df4709Smrg       }
296043df4709Smrg       return Success;
296143df4709Smrg   }
296243df4709Smrg
296343df4709Smrg   dstBox.x1 -= crtc->x;
296443df4709Smrg   dstBox.x2 -= crtc->x;
296543df4709Smrg   dstBox.y1 -= crtc->y;
296643df4709Smrg   dstBox.y2 -= crtc->y;
296743df4709Smrg
296843df4709Smrg   bpp = pScrn->bitsPerPixel >> 3;
296943df4709Smrg
297043df4709Smrg   switch(id) {
297143df4709Smrg   case FOURCC_RGB24:
297243df4709Smrg	dstPitch = width * 4;
297343df4709Smrg	srcPitch = width * 3;
297443df4709Smrg	break;
297543df4709Smrg   case FOURCC_RGBA32:
297643df4709Smrg	dstPitch = width * 4;
297743df4709Smrg	srcPitch = width * 4;
297843df4709Smrg	break;
297943df4709Smrg   case FOURCC_RGB16:
298043df4709Smrg   case FOURCC_RGBT16:
298143df4709Smrg	dstPitch = width * 2;
298243df4709Smrg	srcPitch = RADEON_ALIGN(width * 2, 4);
298343df4709Smrg	break;
298443df4709Smrg   case FOURCC_YV12:
298543df4709Smrg   case FOURCC_I420:
298643df4709Smrg	/* it seems rs4xx chips (all of them???) either can't handle planar
298743df4709Smrg	   yuv at all or would need some unknown different setup. */
298843df4709Smrg       if ((info->ChipFamily != CHIP_FAMILY_RS400) &&
298943df4709Smrg	   (info->ChipFamily != CHIP_FAMILY_RS480)) {
299043df4709Smrg	    /* need 16bytes alignment for u,v plane, so 2 times that for width
299143df4709Smrg	       but blitter needs 64bytes alignment. 128byte is a waste but dstpitch
299243df4709Smrg	       for uv planes needs to be dstpitch yplane >> 1 for now. */
299343df4709Smrg	    dstPitch = (RADEON_ALIGN(width, 128));
299443df4709Smrg	    srcPitch = RADEON_ALIGN(width, 4);
299543df4709Smrg	}
299643df4709Smrg	else {
299743df4709Smrg	    dstPitch = width * 2;
299843df4709Smrg	    srcPitch = RADEON_ALIGN(width, 4);
299943df4709Smrg	    idconv = FOURCC_YUY2;
300043df4709Smrg	}
300143df4709Smrg	break;
300243df4709Smrg   case FOURCC_UYVY:
300343df4709Smrg   case FOURCC_YUY2:
300443df4709Smrg   default:
300543df4709Smrg	dstPitch = width * 2;
300643df4709Smrg	srcPitch = width * 2;
300743df4709Smrg	break;
300843df4709Smrg   }
300943df4709Smrg
301043df4709Smrg#ifdef XF86DRI
301143df4709Smrg   if (info->directRenderingEnabled && info->DMAForXv) {
301243df4709Smrg       /* The upload blit only supports multiples of 64 bytes */
301343df4709Smrg       dstPitch = RADEON_ALIGN(dstPitch, 64);
301443df4709Smrg   } else
301543df4709Smrg#endif
301643df4709Smrg       /* The overlay only supports multiples of 16 bytes */
301743df4709Smrg       dstPitch = RADEON_ALIGN(dstPitch, 16);
301843df4709Smrg
301943df4709Smrg   new_size = dstPitch * height;
302043df4709Smrg   if (idconv == FOURCC_YV12 || id == FOURCC_I420) {
302143df4709Smrg      new_size += (dstPitch >> 1) * (RADEON_ALIGN(height, 2));
302243df4709Smrg   }
302343df4709Smrg   pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
302443df4709Smrg						       (pPriv->doubleBuffer ?
302543df4709Smrg						       (new_size * 2) : new_size), 64,
302643df4709Smrg						       RADEON_GEM_DOMAIN_VRAM);
302743df4709Smrg   if (pPriv->video_offset == 0)
302843df4709Smrg      return BadAlloc;
302943df4709Smrg
303043df4709Smrg   pPriv->currentBuffer ^= 1;
303143df4709Smrg
303243df4709Smrg    /* copy data */
303343df4709Smrg   top = ya >> 16;
303443df4709Smrg   left = (xa >> 16) & ~1;
303543df4709Smrg   npixels = ((xb + 0xffff) >> 16) - left;
303643df4709Smrg
303743df4709Smrg   offset = (pPriv->video_offset) + (top * dstPitch);
303843df4709Smrg
303943df4709Smrg   if(pPriv->doubleBuffer) {
304043df4709Smrg	unsigned char *RADEONMMIO = info->MMIO;
304143df4709Smrg
304243df4709Smrg	/* Wait for last flip to take effect */
304343df4709Smrg	while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK));
304443df4709Smrg
304543df4709Smrg	offset += pPriv->currentBuffer * new_size;
304643df4709Smrg   }
304743df4709Smrg
304843df4709Smrg   dst_start = info->FB + offset;
304943df4709Smrg
305043df4709Smrg   switch(id) {
305143df4709Smrg   case FOURCC_YV12:
305243df4709Smrg   case FOURCC_I420:
305343df4709Smrg	if (id == idconv) {
305443df4709Smrg	    /* meh. Such a mess just for someone who wants to watch half the video clipped */
305543df4709Smrg	    top &= ~1;
305643df4709Smrg	    /* odd number of pixels? That may not work correctly */
305743df4709Smrg	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
305843df4709Smrg	    /* odd number of lines? Maybe... */
305943df4709Smrg	    s2offset = srcPitch * (RADEON_ALIGN(height, 2));
306043df4709Smrg	    s3offset = s2offset + srcPitch2 * ((height + 1) >> 1);
306143df4709Smrg	    s2offset += (top >> 1) * srcPitch2 + (left >> 1);
306243df4709Smrg	    s3offset += (top >> 1) * srcPitch2 + (left >> 1);
306343df4709Smrg	    d2line = (height * dstPitch);
306443df4709Smrg	    d3line = d2line + ((height + 1) >> 1) * (dstPitch >> 1);
306543df4709Smrg	    nlines = ((yb + 0xffff) >> 16) - top;
306643df4709Smrg	    d2line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
306743df4709Smrg	    d3line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
306843df4709Smrg	    if(id == FOURCC_YV12) {
306943df4709Smrg		tmp = s2offset;
307043df4709Smrg		s2offset = s3offset;
307143df4709Smrg		s3offset = tmp;
307243df4709Smrg	    }
307343df4709Smrg	    RADEONCopyData(pScrn, buf + (top * srcPitch) + left, dst_start + left,
307443df4709Smrg		srcPitch, dstPitch, nlines, npixels, 1);
307543df4709Smrg	    RADEONCopyData(pScrn, buf + s2offset, dst_start + d2line + (left >> 1),
307643df4709Smrg		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
307743df4709Smrg	    RADEONCopyData(pScrn, buf + s3offset, dst_start + d3line + (left >> 1),
307843df4709Smrg		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
307943df4709Smrg	}
308043df4709Smrg	else {
308143df4709Smrg	    s2offset = srcPitch * height;
308243df4709Smrg	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
308343df4709Smrg	    s3offset = (srcPitch2 * (height >> 1)) + s2offset;
308443df4709Smrg	    top &= ~1;
308543df4709Smrg	    dst_start += left << 1;
308643df4709Smrg	    tmp = ((top >> 1) * srcPitch2) + (left >> 1);
308743df4709Smrg	    s2offset += tmp;
308843df4709Smrg	    s3offset += tmp;
308943df4709Smrg	    if(id == FOURCC_I420) {
309043df4709Smrg		tmp = s2offset;
309143df4709Smrg		s2offset = s3offset;
309243df4709Smrg		s3offset = tmp;
309343df4709Smrg	    }
309443df4709Smrg	    nlines = ((yb + 0xffff) >> 16) - top;
309543df4709Smrg	    RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left,
309643df4709Smrg				 buf + s2offset, buf + s3offset, dst_start,
309743df4709Smrg				 srcPitch, srcPitch2, dstPitch, nlines, npixels);
309843df4709Smrg	}
309943df4709Smrg	break;
310043df4709Smrg    case FOURCC_RGBT16:
310143df4709Smrg    case FOURCC_RGB16:
310243df4709Smrg    case FOURCC_UYVY:
310343df4709Smrg    case FOURCC_YUY2:
310443df4709Smrg    default:
310543df4709Smrg	left <<= 1;
310643df4709Smrg	buf += (top * srcPitch) + left;
310743df4709Smrg	nlines = ((yb + 0xffff) >> 16) - top;
310843df4709Smrg	dst_start += left;
310943df4709Smrg	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2);
311043df4709Smrg	break;
311143df4709Smrg    case FOURCC_RGBA32:
311243df4709Smrg	buf += (top * srcPitch) + left*4;
311343df4709Smrg	nlines = ((yb + 0xffff) >> 16) - top;
311443df4709Smrg	dst_start += left*4;
311543df4709Smrg	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4);
311643df4709Smrg    	break;
311743df4709Smrg    case FOURCC_RGB24:
311843df4709Smrg	buf += (top * srcPitch) + left*3;
311943df4709Smrg	nlines = ((yb + 0xffff) >> 16) - top;
312043df4709Smrg	dst_start += left*4;
312143df4709Smrg	RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels);
312243df4709Smrg    	break;
312343df4709Smrg    }
312443df4709Smrg
312543df4709Smrg    /* update cliplist */
312643df4709Smrg    if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
312743df4709Smrg    {
312843df4709Smrg	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
312943df4709Smrg	/* draw these */
313043df4709Smrg	if(pPriv->autopaint_colorkey)
313143df4709Smrg	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
313243df4709Smrg    }
313343df4709Smrg
313443df4709Smrg    /* FIXME: someone should look at these offsets, I don't think it makes sense how
313543df4709Smrg              they are handled throughout the source. */
313643df4709Smrg    RADEONDisplayVideo(pScrn, crtc, pPriv, idconv, pPriv->video_offset, offset,
313743df4709Smrg		       offset + d2line, offset + d3line, offset, offset + d2line,
313843df4709Smrg		       offset + d3line, width, height, dstPitch, xa, xb, ya,
313943df4709Smrg		       &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
314043df4709Smrg
314143df4709Smrg    pPriv->videoStatus = CLIENT_VIDEO_ON;
314243df4709Smrg
314343df4709Smrg    info->VideoTimerCallback = RADEONVideoTimerCallback;
314443df4709Smrg
314543df4709Smrg    return Success;
314643df4709Smrg}
314743df4709Smrg
314843df4709Smrg
314943df4709Smrgint
315043df4709SmrgRADEONQueryImageAttributes(
315143df4709Smrg    ScrnInfoPtr pScrn,
315243df4709Smrg    int id,
315343df4709Smrg    unsigned short *w, unsigned short *h,
315443df4709Smrg    int *pitches, int *offsets
315543df4709Smrg){
315643df4709Smrg    const RADEONInfoRec * const info = RADEONPTR(pScrn);
315743df4709Smrg    int size, tmp;
315843df4709Smrg
315943df4709Smrg    if(*w > info->xv_max_width) *w = info->xv_max_width;
316043df4709Smrg    if(*h > info->xv_max_height) *h = info->xv_max_height;
316143df4709Smrg
316243df4709Smrg    *w = RADEON_ALIGN(*w, 2);
316343df4709Smrg    if(offsets) offsets[0] = 0;
316443df4709Smrg
316543df4709Smrg    switch(id) {
316643df4709Smrg    case FOURCC_YV12:
316743df4709Smrg    case FOURCC_I420:
316843df4709Smrg	*h = RADEON_ALIGN(*h, 2);
316943df4709Smrg	size = RADEON_ALIGN(*w, 4);
317043df4709Smrg	if(pitches) pitches[0] = size;
317143df4709Smrg	size *= *h;
317243df4709Smrg	if(offsets) offsets[1] = size;
317343df4709Smrg	tmp = RADEON_ALIGN(*w >> 1, 4);
317443df4709Smrg	if(pitches) pitches[1] = pitches[2] = tmp;
317543df4709Smrg	tmp *= (*h >> 1);
317643df4709Smrg	size += tmp;
317743df4709Smrg	if(offsets) offsets[2] = size;
317843df4709Smrg	size += tmp;
317943df4709Smrg	break;
318043df4709Smrg    case FOURCC_RGBA32:
318143df4709Smrg	size = *w << 2;
318243df4709Smrg	if(pitches) pitches[0] = size;
318343df4709Smrg	size *= *h;
318443df4709Smrg	break;
318543df4709Smrg    case FOURCC_RGB24:
318643df4709Smrg	size = *w * 3;
318743df4709Smrg	if(pitches) pitches[0] = size;
318843df4709Smrg	size *= *h;
318943df4709Smrg	break;
319043df4709Smrg    case FOURCC_RGBT16:
319143df4709Smrg    case FOURCC_RGB16:
319243df4709Smrg    case FOURCC_UYVY:
319343df4709Smrg    case FOURCC_YUY2:
319443df4709Smrg    default:
319543df4709Smrg	size = *w << 1;
319643df4709Smrg	if(pitches) pitches[0] = size;
319743df4709Smrg	size *= *h;
319843df4709Smrg	break;
319943df4709Smrg    }
320043df4709Smrg
320143df4709Smrg    return size;
320243df4709Smrg}
320343df4709Smrg
320443df4709Smrgstatic void
320543df4709SmrgRADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now)
320643df4709Smrg{
320743df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
320843df4709Smrg    RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
320943df4709Smrg
321043df4709Smrg    if(pPriv->videoStatus & TIMER_MASK) {
321143df4709Smrg	if(pPriv->videoStatus & OFF_TIMER) {
321243df4709Smrg	    if(pPriv->offTime < now) {
321343df4709Smrg		unsigned char *RADEONMMIO = info->MMIO;
321443df4709Smrg		OUTREG(RADEON_OV0_SCALE_CNTL, 0);
321543df4709Smrg		pPriv->videoStatus = FREE_TIMER;
321643df4709Smrg		pPriv->freeTime = now + FREE_DELAY;
321743df4709Smrg	    }
321843df4709Smrg	} else {  /* FREE_TIMER */
321943df4709Smrg	    if(pPriv->freeTime < now) {
322043df4709Smrg		RADEONFreeVideoMemory(pScrn, pPriv);
322143df4709Smrg		pPriv->videoStatus = 0;
322243df4709Smrg		info->VideoTimerCallback = NULL;
322343df4709Smrg	    }
322443df4709Smrg	}
322543df4709Smrg    } else  /* shouldn't get here */
322643df4709Smrg	info->VideoTimerCallback = NULL;
322743df4709Smrg}
322843df4709Smrg
322943df4709Smrg/****************** Offscreen stuff ***************/
323043df4709Smrgtypedef struct {
323143df4709Smrg  void *surface_memory;
323243df4709Smrg  Bool isOn;
323343df4709Smrg} OffscreenPrivRec, * OffscreenPrivPtr;
323443df4709Smrg
323543df4709Smrgstatic int
323643df4709SmrgRADEONAllocateSurface(
323743df4709Smrg    ScrnInfoPtr pScrn,
323843df4709Smrg    int id,
323943df4709Smrg    unsigned short w,
324043df4709Smrg    unsigned short h,
324143df4709Smrg    XF86SurfacePtr surface
324243df4709Smrg){
324343df4709Smrg    int offset, pitch, size;
324443df4709Smrg    OffscreenPrivPtr pPriv;
324543df4709Smrg    void *surface_memory = NULL;
324643df4709Smrg    if((w > 1024) || (h > 1024))
324743df4709Smrg	return BadAlloc;
324843df4709Smrg
324943df4709Smrg    w = RADEON_ALIGN(w, 2);
325043df4709Smrg    pitch = RADEON_ALIGN(w << 1, 16);
325143df4709Smrg    size = pitch * h;
325243df4709Smrg
325343df4709Smrg    offset = radeon_legacy_allocate_memory(pScrn, &surface_memory, size, 64,
325443df4709Smrg		    RADEON_GEM_DOMAIN_VRAM);
325543df4709Smrg    if (offset == 0)
325643df4709Smrg	return BadAlloc;
325743df4709Smrg
325843df4709Smrg    surface->width = w;
325943df4709Smrg    surface->height = h;
326043df4709Smrg
326143df4709Smrg    if(!(surface->pitches = malloc(sizeof(int)))) {
326243df4709Smrg	radeon_legacy_free_memory(pScrn, surface_memory);
326343df4709Smrg	return BadAlloc;
326443df4709Smrg    }
326543df4709Smrg    if(!(surface->offsets = malloc(sizeof(int)))) {
326643df4709Smrg	free(surface->pitches);
326743df4709Smrg	radeon_legacy_free_memory(pScrn, surface_memory);
326843df4709Smrg	return BadAlloc;
326943df4709Smrg    }
327043df4709Smrg    if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) {
327143df4709Smrg	free(surface->pitches);
327243df4709Smrg	free(surface->offsets);
327343df4709Smrg	radeon_legacy_free_memory(pScrn, surface_memory);
327443df4709Smrg	return BadAlloc;
327543df4709Smrg    }
327643df4709Smrg
327743df4709Smrg    pPriv->surface_memory = surface_memory;
327843df4709Smrg    pPriv->isOn = FALSE;
327943df4709Smrg
328043df4709Smrg    surface->pScrn = pScrn;
328143df4709Smrg    surface->id = id;
328243df4709Smrg    surface->pitches[0] = pitch;
328343df4709Smrg    surface->offsets[0] = offset;
328443df4709Smrg    surface->devPrivate.ptr = (pointer)pPriv;
328543df4709Smrg
328643df4709Smrg    return Success;
328743df4709Smrg}
328843df4709Smrg
328943df4709Smrgstatic int
329043df4709SmrgRADEONStopSurface(
329143df4709Smrg    XF86SurfacePtr surface
329243df4709Smrg){
329343df4709Smrg  OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
329443df4709Smrg  RADEONInfoPtr info = RADEONPTR(surface->pScrn);
329543df4709Smrg  unsigned char *RADEONMMIO = info->MMIO;
329643df4709Smrg
329743df4709Smrg  if(pPriv->isOn) {
329843df4709Smrg	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
329943df4709Smrg	pPriv->isOn = FALSE;
330043df4709Smrg  }
330143df4709Smrg  return Success;
330243df4709Smrg}
330343df4709Smrg
330443df4709Smrg
330543df4709Smrgstatic int
330643df4709SmrgRADEONFreeSurface(
330743df4709Smrg    XF86SurfacePtr surface
330843df4709Smrg){
330943df4709Smrg    ScrnInfoPtr pScrn = surface->pScrn;
331043df4709Smrg    OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
331143df4709Smrg
331243df4709Smrg    if(pPriv->isOn)
331343df4709Smrg	RADEONStopSurface(surface);
331443df4709Smrg    radeon_legacy_free_memory(pScrn, pPriv->surface_memory);
331543df4709Smrg    pPriv->surface_memory = NULL;
331643df4709Smrg    free(surface->pitches);
331743df4709Smrg    free(surface->offsets);
331843df4709Smrg    free(surface->devPrivate.ptr);
331943df4709Smrg
332043df4709Smrg    return Success;
332143df4709Smrg}
332243df4709Smrg
332343df4709Smrgstatic int
332443df4709SmrgRADEONGetSurfaceAttribute(
332543df4709Smrg    ScrnInfoPtr pScrn,
332643df4709Smrg    Atom attribute,
332743df4709Smrg    INT32 *value
332843df4709Smrg){
332943df4709Smrg   return RADEONGetPortAttribute(pScrn, attribute, value,
333043df4709Smrg		(pointer)(GET_PORT_PRIVATE(pScrn)));
333143df4709Smrg}
333243df4709Smrg
333343df4709Smrgstatic int
333443df4709SmrgRADEONSetSurfaceAttribute(
333543df4709Smrg    ScrnInfoPtr pScrn,
333643df4709Smrg    Atom attribute,
333743df4709Smrg    INT32 value
333843df4709Smrg){
333943df4709Smrg   return RADEONSetPortAttribute(pScrn, attribute, value,
334043df4709Smrg		(pointer)(GET_PORT_PRIVATE(pScrn)));
334143df4709Smrg}
334243df4709Smrg
334343df4709Smrg
334443df4709Smrgstatic int
334543df4709SmrgRADEONDisplaySurface(
334643df4709Smrg    XF86SurfacePtr surface,
334743df4709Smrg    short src_x, short src_y,
334843df4709Smrg    short drw_x, short drw_y,
334943df4709Smrg    short src_w, short src_h,
335043df4709Smrg    short drw_w, short drw_h,
335143df4709Smrg    RegionPtr clipBoxes
335243df4709Smrg){
335343df4709Smrg    OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
335443df4709Smrg    ScrnInfoPtr pScrn = surface->pScrn;
335543df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
335643df4709Smrg    RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
335743df4709Smrg
335843df4709Smrg    INT32 xa, ya, xb, yb;
335943df4709Smrg    BoxRec dstBox;
336043df4709Smrg    xf86CrtcPtr crtc;
336143df4709Smrg
336243df4709Smrg    if (src_w > (drw_w << 4))
336343df4709Smrg	drw_w = src_w >> 4;
336443df4709Smrg    if (src_h > (drw_h << 4))
336543df4709Smrg	drw_h = src_h >> 4;
336643df4709Smrg
336743df4709Smrg    xa = src_x;
336843df4709Smrg    xb = src_x + src_w;
336943df4709Smrg    ya = src_y;
337043df4709Smrg    yb = src_y + src_h;
337143df4709Smrg
337243df4709Smrg    dstBox.x1 = drw_x;
337343df4709Smrg    dstBox.x2 = drw_x + drw_w;
337443df4709Smrg    dstBox.y1 = drw_y;
337543df4709Smrg    dstBox.y2 = drw_y + drw_h;
337643df4709Smrg
337743df4709Smrg    if (!radeon_crtc_clip_video(pScrn, &crtc, portPriv->desired_crtc,
337843df4709Smrg				&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
337943df4709Smrg				surface->width, surface->height))
338043df4709Smrg        return Success;
338143df4709Smrg
338243df4709Smrg   if (!crtc) {
338343df4709Smrg       if (pPriv->isOn) {
338443df4709Smrg	   unsigned char *RADEONMMIO = info->MMIO;
338543df4709Smrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
338643df4709Smrg	   pPriv->isOn = FALSE;
338743df4709Smrg       }
338843df4709Smrg       return Success;
338943df4709Smrg   }
339043df4709Smrg
339143df4709Smrg    dstBox.x1 -= crtc->x;
339243df4709Smrg    dstBox.x2 -= crtc->x;
339343df4709Smrg    dstBox.y1 -= crtc->y;
339443df4709Smrg    dstBox.y2 -= crtc->y;
339543df4709Smrg
339643df4709Smrg#if 0
339743df4709Smrg    /* this isn't needed */
339843df4709Smrg    RADEONResetVideo(pScrn);
339943df4709Smrg#endif
340043df4709Smrg    RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id,
340143df4709Smrg		       surface->offsets[0], surface->offsets[0],
340243df4709Smrg		       surface->offsets[0], surface->offsets[0],
340343df4709Smrg		       surface->offsets[0], surface->offsets[0],
340443df4709Smrg		       surface->offsets[0], surface->width, surface->height,
340543df4709Smrg		       surface->pitches[0], xa, xb, ya, &dstBox, src_w, src_h,
340643df4709Smrg		       drw_w, drw_h, METHOD_BOB);
340743df4709Smrg
340843df4709Smrg    if (portPriv->autopaint_colorkey)
340943df4709Smrg	xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
341043df4709Smrg
341143df4709Smrg    pPriv->isOn = TRUE;
341243df4709Smrg    /* we've prempted the XvImage stream so set its free timer */
341343df4709Smrg    if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
341443df4709Smrg	REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
341543df4709Smrg	UpdateCurrentTime();
341643df4709Smrg	portPriv->videoStatus = FREE_TIMER;
341743df4709Smrg	portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
341843df4709Smrg	info->VideoTimerCallback = RADEONVideoTimerCallback;
341943df4709Smrg    }
342043df4709Smrg
342143df4709Smrg    return Success;
3422209ff23fSmrg}
342343df4709Smrg
342443df4709Smrg
342543df4709Smrgstatic void
342643df4709SmrgRADEONInitOffscreenImages(ScreenPtr pScreen)
342743df4709Smrg{
342843df4709Smrg/*  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
342943df4709Smrg    RADEONInfoPtr info = RADEONPTR(pScrn); */
343043df4709Smrg    XF86OffscreenImagePtr offscreenImages;
343143df4709Smrg    /* need to free this someplace */
343243df4709Smrg
343343df4709Smrg    if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec))))
343443df4709Smrg	return;
343543df4709Smrg
343643df4709Smrg    offscreenImages[0].image = &Images[0];
343743df4709Smrg    offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*|
343843df4709Smrg			       VIDEO_CLIP_TO_VIEWPORT*/;
343943df4709Smrg    offscreenImages[0].alloc_surface = RADEONAllocateSurface;
344043df4709Smrg    offscreenImages[0].free_surface = RADEONFreeSurface;
344143df4709Smrg    offscreenImages[0].display = RADEONDisplaySurface;
344243df4709Smrg    offscreenImages[0].stop = RADEONStopSurface;
344343df4709Smrg    offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute;
344443df4709Smrg    offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute;
344543df4709Smrg    offscreenImages[0].max_width = 2047;
344643df4709Smrg    offscreenImages[0].max_height = 2047;
344743df4709Smrg    offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
344843df4709Smrg    offscreenImages[0].attributes = Attributes;
344943df4709Smrg
345043df4709Smrg    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
345143df4709Smrg}
345243df4709Smrg
345343df4709Smrg         /* TV-in functions */
345443df4709Smrg
345543df4709Smrgstatic int
345643df4709SmrgRADEONPutVideo(
345743df4709Smrg  ScrnInfoPtr pScrn,
345843df4709Smrg  short src_x, short src_y,
345943df4709Smrg  short drw_x, short drw_y,
346043df4709Smrg  short src_w, short src_h,
346143df4709Smrg  short drw_w, short drw_h,
346243df4709Smrg  RegionPtr clipBoxes, pointer data,
346343df4709Smrg  DrawablePtr pDraw
346443df4709Smrg){
346543df4709Smrg   RADEONInfoPtr info = RADEONPTR(pScrn);
346643df4709Smrg   RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
346743df4709Smrg   unsigned char *RADEONMMIO = info->MMIO;
346843df4709Smrg   INT32 xa, xb, ya, yb, top;
346943df4709Smrg   unsigned int pitch, new_size, alloc_size;
347043df4709Smrg   unsigned int offset1, offset2, offset3, offset4, s2offset, s3offset;
347143df4709Smrg   unsigned int vbi_offset0, vbi_offset1;
347243df4709Smrg   int srcPitch, srcPitch2, dstPitch;
347343df4709Smrg   int bpp;
347443df4709Smrg   BoxRec dstBox;
347543df4709Smrg   uint32_t id, display_base;
347643df4709Smrg   int width, height;
347743df4709Smrg   int mult;
347843df4709Smrg   int vbi_line_width, vbi_start, vbi_end;
347943df4709Smrg   xf86CrtcPtr crtc;
348043df4709Smrg
348143df4709Smrg    RADEON_SYNC(info, pScrn);
348243df4709Smrg   /*
348343df4709Smrg    * s2offset, s3offset - byte offsets into U and V plane of the
348443df4709Smrg    *                      source where copying starts.  Y plane is
348543df4709Smrg    *                      done by editing "buf".
348643df4709Smrg    *
348743df4709Smrg    * offset - byte offset to the first line of the destination.
348843df4709Smrg    *
348943df4709Smrg    * dst_start - byte address to the first displayed pel.
349043df4709Smrg    *
349143df4709Smrg    */
349243df4709Smrg
349343df4709Smrg   /* make the compiler happy */
349443df4709Smrg   s2offset = s3offset = srcPitch2 = 0;
349543df4709Smrg
349643df4709Smrg   if(src_w > (drw_w << 4))
349743df4709Smrg        drw_w = src_w >> 4;
349843df4709Smrg   if(src_h > (drw_h << 4))
349943df4709Smrg        drw_h = src_h >> 4;
350043df4709Smrg
350143df4709Smrg   /* Clip */
350243df4709Smrg   xa = src_x;
350343df4709Smrg   xb = src_x + src_w;
350443df4709Smrg   ya = src_y;
350543df4709Smrg   yb = src_y + src_h;
350643df4709Smrg
350743df4709Smrg   dstBox.x1 = drw_x;
350843df4709Smrg   dstBox.x2 = drw_x + drw_w;
350943df4709Smrg   dstBox.y1 = drw_y;
351043df4709Smrg   dstBox.y2 = drw_y + drw_h;
351143df4709Smrg
351243df4709Smrg   width = InputVideoEncodings[pPriv->encoding].width;
351343df4709Smrg   height = InputVideoEncodings[pPriv->encoding].height;
351443df4709Smrg
351543df4709Smrg   vbi_line_width = 798*2;
351643df4709Smrg   if(width<=640)
351743df4709Smrg       vbi_line_width = 0x640; /* 1600 actually */
351843df4709Smrg   else
351943df4709Smrg       vbi_line_width = 2000; /* might need adjustment */
352043df4709Smrg
352143df4709Smrg   if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
352243df4709Smrg			       &dstBox, &xa, &xb, &ya, &yb,
352343df4709Smrg			       clipBoxes, width, height))
352443df4709Smrg       return Success;
352543df4709Smrg
352643df4709Smrg   if (!crtc) {
352743df4709Smrg       if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
352843df4709Smrg	   unsigned char *RADEONMMIO = info->MMIO;
352943df4709Smrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
353043df4709Smrg	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
353143df4709Smrg       }
353243df4709Smrg       return Success;
353343df4709Smrg   }
353443df4709Smrg
353543df4709Smrg   dstBox.x1 -= crtc->x;
353643df4709Smrg   dstBox.x2 -= crtc->x;
353743df4709Smrg   dstBox.y1 -= crtc->y;
353843df4709Smrg   dstBox.y2 -= crtc->y;
353943df4709Smrg
354043df4709Smrg   bpp = pScrn->bitsPerPixel >> 3;
354143df4709Smrg   pitch = bpp * pScrn->displayWidth;
354243df4709Smrg
354343df4709Smrg   switch(pPriv->overlay_deinterlacing_method){
354443df4709Smrg        case METHOD_BOB:
354543df4709Smrg        case METHOD_SINGLE:
354643df4709Smrg                mult=2;
354743df4709Smrg                break;
354843df4709Smrg        case METHOD_WEAVE:
354943df4709Smrg        case METHOD_ADAPTIVE:
355043df4709Smrg                mult=4;
355143df4709Smrg                break;
355243df4709Smrg        default:
355343df4709Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n");
355443df4709Smrg                mult=4;
355543df4709Smrg        }
355643df4709Smrg
355743df4709Smrg   id = FOURCC_YUY2;
355843df4709Smrg
355943df4709Smrg   top = ya>>16;
356043df4709Smrg#if 0
356143df4709Smrg   /* setting the ID above makes this useful - needs revisiting */
356243df4709Smrg   switch(id) {
356343df4709Smrg   case FOURCC_YV12:
356443df4709Smrg   case FOURCC_I420:
356543df4709Smrg        top &= ~1;
356643df4709Smrg        dstPitch = RADEON_ALIGN(width << 1, 16);
356743df4709Smrg        srcPitch = RADEON_ALIGN(width, 4);
356843df4709Smrg        s2offset = srcPitch * height;
356943df4709Smrg        srcPitch2 = RADEON_ALIGN(width >> 1, 4);
357043df4709Smrg        s3offset = (srcPitch2 * (height >> 1)) + s2offset;
357143df4709Smrg        break;
357243df4709Smrg   case FOURCC_UYVY:
357343df4709Smrg   case FOURCC_YUY2:
357443df4709Smrg   default:
357543df4709Smrg        dstPitch = RADEON_ALIGN(width<<1, 16);
357643df4709Smrg        srcPitch = (width<<1);
357743df4709Smrg        break;
357843df4709Smrg   }
357943df4709Smrg#else
358043df4709Smrg   dstPitch = RADEON_ALIGN(width << 1, 16);
358143df4709Smrg   srcPitch = (width<<1);
358243df4709Smrg#endif
358343df4709Smrg
358443df4709Smrg   new_size = dstPitch * height;
358543df4709Smrg   new_size = new_size + 0x1f; /* for aligning */
358643df4709Smrg   alloc_size = new_size * mult;
358743df4709Smrg   if (pPriv->capture_vbi_data)
358843df4709Smrg      alloc_size += 2 * 2 * vbi_line_width * 21;
358943df4709Smrg
359043df4709Smrg   pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
359143df4709Smrg						      (pPriv->doubleBuffer ?
359243df4709Smrg						      (new_size * 2) : new_size), 64,
359343df4709Smrg						      RADEON_GEM_DOMAIN_GTT);
359443df4709Smrg   if (pPriv->video_offset == 0)
359543df4709Smrg      return BadAlloc;
359643df4709Smrg
359743df4709Smrg/* I have suspicion that capture engine must be active _before_ Rage Theatre
359843df4709Smrg   is being manipulated with.. */
359943df4709Smrg
360043df4709Smrg   RADEONWaitForIdleMMIO(pScrn);
360143df4709Smrg   display_base=INREG(RADEON_DISPLAY_BASE_ADDR);
360243df4709Smrg
360343df4709Smrg/*   RADEONWaitForFifo(pScrn, 15); */
360443df4709Smrg
360543df4709Smrg   switch(pPriv->overlay_deinterlacing_method){
360643df4709Smrg        case METHOD_BOB:
360743df4709Smrg        case METHOD_SINGLE:
360843df4709Smrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
360943df4709Smrg           offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
361043df4709Smrg           offset3 = offset1;
361143df4709Smrg           offset4 = offset2;
361243df4709Smrg           break;
361343df4709Smrg        case METHOD_WEAVE:
361443df4709Smrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
361543df4709Smrg           offset2 = offset1+dstPitch;
361643df4709Smrg           offset3 = RADEON_ALIGN(pPriv->video_offset + 2 * new_size, 0x10);
361743df4709Smrg           offset4 = offset3+dstPitch;
361843df4709Smrg           break;
361943df4709Smrg        default:
362043df4709Smrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
362143df4709Smrg           offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
362243df4709Smrg           offset3 = offset1;
362343df4709Smrg           offset4 = offset2;
362443df4709Smrg        }
362543df4709Smrg
362643df4709Smrg   OUTREG(RADEON_CAP0_BUF0_OFFSET,        offset1+display_base);
362743df4709Smrg   OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET,   offset2+display_base);
362843df4709Smrg   OUTREG(RADEON_CAP0_BUF1_OFFSET,        offset3+display_base);
362943df4709Smrg   OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET,   offset4+display_base);
363043df4709Smrg
363143df4709Smrg   OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base);
363243df4709Smrg
363343df4709Smrg   if(pPriv->capture_vbi_data){
363443df4709Smrg        if ((pPriv->encoding==2)||(pPriv->encoding==8)) {
363543df4709Smrg            /* PAL, SECAM */
363643df4709Smrg            vbi_start = 5;
363743df4709Smrg            vbi_end = 21;
363843df4709Smrg        } else {
363943df4709Smrg            /* NTSC */
364043df4709Smrg            vbi_start = 8;
364143df4709Smrg            vbi_end = 20;
364243df4709Smrg        }
364343df4709Smrg
364443df4709Smrg        vbi_offset0 = RADEON_ALIGN(pPriv->video_offset + mult * new_size * bpp, 0x10);
364543df4709Smrg        vbi_offset1 = vbi_offset0 + dstPitch*20;
364643df4709Smrg        OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base);
364743df4709Smrg        OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base);
364843df4709Smrg        OUTREG(RADEON_CAP0_VBI2_OFFSET, 0);
364943df4709Smrg        OUTREG(RADEON_CAP0_VBI3_OFFSET, 0);
365043df4709Smrg        OUTREG(RADEON_CAP0_VBI_V_WINDOW, vbi_start | (vbi_end<<16));
365143df4709Smrg        OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16);
365243df4709Smrg        }
365343df4709Smrg
365443df4709Smrg   OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2);
365543df4709Smrg   OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16);
365643df4709Smrg   OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1));
365743df4709Smrg   if(mult==2){
365843df4709Smrg           OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB);
365943df4709Smrg           } else {
366043df4709Smrg           OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE);
366143df4709Smrg           }
366243df4709Smrg   OUTREG(RADEON_CAP0_DEBUG, 0);
366343df4709Smrg
366443df4709Smrg   OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01);
366543df4709Smrg   OUTREG(RADEON_TEST_DEBUG_CNTL, 0);
366643df4709Smrg
366743df4709Smrg   if(! pPriv->video_stream_active)
366843df4709Smrg   {
366943df4709Smrg
367043df4709Smrg      RADEONWaitForIdleMMIO(pScrn);
367143df4709Smrg      OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 );
367243df4709Smrg      OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0);
367343df4709Smrg      OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK);
367443df4709Smrg      OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11);
367543df4709Smrg      if(pPriv->theatre != NULL)
367643df4709Smrg      {
367743df4709Smrg         RADEON_RT_SetEncoding(pScrn, pPriv);
367843df4709Smrg      }
367943df4709Smrg      if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
368043df4709Smrg      if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
368143df4709Smrg      if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
368243df4709Smrg      if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
368343df4709Smrg   }
368443df4709Smrg
368543df4709Smrg
368643df4709Smrg   /* update cliplist */
368743df4709Smrg   if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
368843df4709Smrg        REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
368943df4709Smrg        /* draw these */
369043df4709Smrg        if(pPriv->autopaint_colorkey)
369143df4709Smrg	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
369243df4709Smrg   }
369343df4709Smrg
369443df4709Smrg   RADEONDisplayVideo(pScrn, crtc, pPriv, id, pPriv->video_offset,
369543df4709Smrg		      offset1+top*srcPitch, offset2+top*srcPitch,
369643df4709Smrg		      offset3+top*srcPitch, offset4+top*srcPitch,
369743df4709Smrg		      offset1+top*srcPitch, offset2+top*srcPitch, width, height,
369843df4709Smrg		      dstPitch*mult/2, xa, xb, ya, &dstBox, src_w, src_h*mult/2,
369943df4709Smrg		      drw_w, drw_h, pPriv->overlay_deinterlacing_method);
370043df4709Smrg
370143df4709Smrg   RADEONWaitForFifo(pScrn, 1);
370243df4709Smrg   OUTREG(RADEON_OV0_REG_LOAD_CNTL,  RADEON_REG_LD_CTL_LOCK);
370343df4709Smrg   RADEONWaitForIdleMMIO(pScrn);
370443df4709Smrg   while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
370543df4709Smrg
370643df4709Smrg
370743df4709Smrg   switch(pPriv->overlay_deinterlacing_method){
370843df4709Smrg        case METHOD_BOB:
370943df4709Smrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
371043df4709Smrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/
371143df4709Smrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
371243df4709Smrg           break;
371343df4709Smrg        case METHOD_SINGLE:
371443df4709Smrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
371543df4709Smrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
371643df4709Smrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
371743df4709Smrg           break;
371843df4709Smrg        case METHOD_WEAVE:
371943df4709Smrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28));
372043df4709Smrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0  |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
372143df4709Smrg                | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN
372243df4709Smrg                /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */
372343df4709Smrg                /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */
372443df4709Smrg                |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE);
372543df4709Smrg           break;
372643df4709Smrg        default:
372743df4709Smrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
372843df4709Smrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
372943df4709Smrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
373043df4709Smrg        }
373143df4709Smrg
373243df4709Smrg
373343df4709Smrg   RADEONWaitForIdleMMIO(pScrn);
373443df4709Smrg   OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
373543df4709Smrg   OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
373643df4709Smrg
373743df4709Smrg   OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
373843df4709Smrg
373943df4709Smrg#if 0
374043df4709Smrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL));
374143df4709Smrg/*   OUTREG(RADEON_OV0_FLAG_CNTL, 8); */
374243df4709Smrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL));
374343df4709Smrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS));
374443df4709Smrg
374543df4709Smrg/*   OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */
374643df4709Smrg#endif
374743df4709Smrg
374843df4709Smrg   pPriv->videoStatus = CLIENT_VIDEO_ON;
374943df4709Smrg   pPriv->video_stream_active = TRUE;
375043df4709Smrg
375143df4709Smrg   info->VideoTimerCallback = RADEONVideoTimerCallback;
375243df4709Smrg
375343df4709Smrg   return Success;
375443df4709Smrg}
375543df4709Smrg        /* miscellaneous TV-in helper functions */
375643df4709Smrg
375743df4709Smrgstatic void RADEON_board_setmisc(RADEONPortPrivPtr pPriv)
375843df4709Smrg{
375943df4709Smrg    /* Adjust PAL/SECAM constants for FI1216MF tuner */
376043df4709Smrg    if((((pPriv->tuner_type & 0xf)==5) ||
376143df4709Smrg        ((pPriv->tuner_type & 0xf)==11)||
376243df4709Smrg        ((pPriv->tuner_type & 0xf)==14))
376343df4709Smrg        && (pPriv->fi1236!=NULL))
376443df4709Smrg    {
376543df4709Smrg        if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/
376643df4709Smrg        {
376743df4709Smrg           pPriv->fi1236->parm.band_low = 0xA1;
376843df4709Smrg           pPriv->fi1236->parm.band_mid = 0x91;
376943df4709Smrg           pPriv->fi1236->parm.band_high = 0x31;
377043df4709Smrg        }
377143df4709Smrg        if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/
377243df4709Smrg        {
377343df4709Smrg           pPriv->fi1236->parm.band_low = 0xA3;
377443df4709Smrg           pPriv->fi1236->parm.band_mid = 0x93;
377543df4709Smrg           pPriv->fi1236->parm.band_high = 0x33;
377643df4709Smrg        }
377743df4709Smrg    }
377843df4709Smrg
377943df4709Smrg}
378043df4709Smrg
378143df4709Smrgstatic void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
378243df4709Smrg{
378343df4709Smrgint width, height;
378443df4709SmrgRADEONWaitForIdleMMIO(pScrn);
378543df4709Smrg
378643df4709Smrg/* Disable VBI capture for anything but TV tuner */
378743df4709Smrgswitch(pPriv->encoding){
378843df4709Smrg	case 2:
378943df4709Smrg	case 5:
379043df4709Smrg	case 8:
379143df4709Smrg		pPriv->capture_vbi_data=1;
379243df4709Smrg		break;
379343df4709Smrg	default:
379443df4709Smrg		pPriv->capture_vbi_data=0;
379543df4709Smrg	}
379643df4709Smrg
379743df4709Smrgswitch(pPriv->encoding){
379843df4709Smrg        case 1:
379943df4709Smrg                xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
380043df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
380143df4709Smrg                pPriv->v=25;
380243df4709Smrg                break;
380343df4709Smrg        case 2:
380443df4709Smrg                xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
380543df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
380643df4709Smrg                pPriv->v=25;
380743df4709Smrg                break;
380843df4709Smrg        case 3:
380943df4709Smrg                xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
381043df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
381143df4709Smrg                pPriv->v=25;
381243df4709Smrg                break;
381343df4709Smrg        case 4:
381443df4709Smrg                xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE,0);
381543df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
381643df4709Smrg                pPriv->v=23;
381743df4709Smrg                break;
381843df4709Smrg        case 5:
381943df4709Smrg                xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
382043df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
382143df4709Smrg                pPriv->v=23;
382243df4709Smrg                break;
382343df4709Smrg        case 6:
382443df4709Smrg                xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
382543df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
382643df4709Smrg                pPriv->v=23;
382743df4709Smrg                break;
382843df4709Smrg        case 7:
382943df4709Smrg                xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE, 0);
383043df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
383143df4709Smrg                pPriv->v=25;
383243df4709Smrg                break;
383343df4709Smrg        case 8:
383443df4709Smrg                xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
383543df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
383643df4709Smrg                pPriv->v=25;
383743df4709Smrg                break;
383843df4709Smrg        case 9:
383943df4709Smrg                xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
384043df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
384143df4709Smrg                pPriv->v=25;
384243df4709Smrg                break;
384343df4709Smrg        case 10:
384443df4709Smrg                xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
384543df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
384643df4709Smrg                pPriv->v=25;
384743df4709Smrg                break;
384843df4709Smrg        case 11:
384943df4709Smrg                xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
385043df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
385143df4709Smrg                pPriv->v=25;
385243df4709Smrg                break;
385343df4709Smrg        case 12:
385443df4709Smrg                xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
385543df4709Smrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
385643df4709Smrg                pPriv->v=25;
385743df4709Smrg                break;
385843df4709Smrg        default:
385943df4709Smrg                pPriv->v=0;
386043df4709Smrg                return;
386143df4709Smrg        }
386243df4709Smrgxf86_RT_SetInterlace(pPriv->theatre, 1);
386343df4709Smrgwidth = InputVideoEncodings[pPriv->encoding].width;
386443df4709Smrgheight = InputVideoEncodings[pPriv->encoding].height;
386543df4709Smrgxf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data);
386643df4709Smrg}
386743df4709Smrg
386843df4709Smrgstatic void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv)
386943df4709Smrg{
387043df4709Smrgxf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
387143df4709Smrgswitch(pPriv->encoding){
387243df4709Smrg        case 1:
387343df4709Smrg                pPriv->msp3430->standard = MSP3430_PAL;
387443df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
387543df4709Smrg                break;
387643df4709Smrg        case 2:
387743df4709Smrg                pPriv->msp3430->standard = MSP3430_PAL;
387843df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
387943df4709Smrg                break;
388043df4709Smrg        case 3:
388143df4709Smrg                pPriv->msp3430->standard = MSP3430_PAL;
388243df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
388343df4709Smrg                break;
388443df4709Smrg        case 4:
388543df4709Smrg                pPriv->msp3430->standard = MSP3430_NTSC;
388643df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
388743df4709Smrg                break;
388843df4709Smrg        case 5:
388943df4709Smrg                pPriv->msp3430->standard = MSP3430_NTSC;
389043df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
389143df4709Smrg                break;
389243df4709Smrg        case 6:
389343df4709Smrg                pPriv->msp3430->standard = MSP3430_NTSC;
389443df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
389543df4709Smrg                break;
389643df4709Smrg        case 7:
389743df4709Smrg                pPriv->msp3430->standard = MSP3430_SECAM;
389843df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
389943df4709Smrg                break;
390043df4709Smrg        case 8:
390143df4709Smrg                pPriv->msp3430->standard = MSP3430_SECAM;
390243df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
390343df4709Smrg                break;
390443df4709Smrg        case 9:
390543df4709Smrg                pPriv->msp3430->standard = MSP3430_SECAM;
390643df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
390743df4709Smrg                break;
390843df4709Smrg        case 10:
390943df4709Smrg                pPriv->msp3430->standard = MSP3430_SECAM;
391043df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
391143df4709Smrg                break;
391243df4709Smrg        case 11:
391343df4709Smrg                pPriv->msp3430->standard = MSP3430_SECAM;
391443df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
391543df4709Smrg                break;
391643df4709Smrg        case 12:
391743df4709Smrg                pPriv->msp3430->standard = MSP3430_SECAM;
391843df4709Smrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
391943df4709Smrg                break;
392043df4709Smrg        default:
392143df4709Smrg                return;
392243df4709Smrg        }
392343df4709Smrgxf86_InitMSP3430(pPriv->msp3430);
392443df4709Smrgxf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
392543df4709Smrg}
392643df4709Smrg
392743df4709Smrgstatic void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv)
392843df4709Smrg{
392943df4709SmrgTDA9885Ptr t=pPriv->tda9885;
393043df4709Smrg
393143df4709Smrgswitch(pPriv->encoding){
393243df4709Smrg                /* PAL */
393343df4709Smrg        case 1:
393443df4709Smrg        case 2:
393543df4709Smrg        case 3:
393643df4709Smrg                t->standard_video_if=2;
393743df4709Smrg                t->standard_sound_carrier=1;
393843df4709Smrg					 t->modulation=2; /* negative FM */
393943df4709Smrg                break;
394043df4709Smrg                /* NTSC */
394143df4709Smrg        case 4:
394243df4709Smrg        case 5:
394343df4709Smrg        case 6:
394443df4709Smrg                t->standard_video_if=1;
394543df4709Smrg                t->standard_sound_carrier=0;
394643df4709Smrg					 t->modulation=2; /* negative FM */
394743df4709Smrg                break;
394843df4709Smrg                /* SECAM */
394943df4709Smrg        case 7:
395043df4709Smrg        case 8:
395143df4709Smrg        case 9:
395243df4709Smrg        case 10:
395343df4709Smrg        case 11:
395443df4709Smrg        case 12:
395543df4709Smrg                t->standard_video_if=0;
395643df4709Smrg                t->standard_sound_carrier=3;
395743df4709Smrg                t->modulation=0; /* positive AM */
395843df4709Smrg                break;
395943df4709Smrg        default:
396043df4709Smrg                return;
396143df4709Smrg        }
396243df4709Smrgxf86_tda9885_setparameters(pPriv->tda9885);
396343df4709Smrgxf86_tda9885_getstatus(pPriv->tda9885);
396443df4709Smrgxf86_tda9885_dumpstatus(pPriv->tda9885);
396543df4709Smrg}
396643df4709Smrg
396743df4709Smrgstatic void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv)
396843df4709Smrg{
396943df4709Smrg/* at the moment this only affect MT2032 */
397043df4709Smrgswitch(pPriv->encoding){
397143df4709Smrg                /* PAL */
397243df4709Smrg        case 1:
397343df4709Smrg        case 2:
397443df4709Smrg        case 3:
397543df4709Smrg		pPriv->fi1236->video_if=38.900;
397643df4709Smrg                break;
397743df4709Smrg                /* NTSC */
397843df4709Smrg        case 4:
397943df4709Smrg        case 5:
398043df4709Smrg        case 6:
398143df4709Smrg		pPriv->fi1236->video_if=45.7812;
398243df4709Smrg		pPriv->fi1236->video_if=45.750;
398343df4709Smrg		pPriv->fi1236->video_if=45.125;
398443df4709Smrg                break;
398543df4709Smrg                /* SECAM */
398643df4709Smrg        case 7:
398743df4709Smrg        case 8:
398843df4709Smrg        case 9:
398943df4709Smrg        case 10:
399043df4709Smrg        case 11:
399143df4709Smrg        case 12:
399243df4709Smrg		pPriv->fi1236->video_if=58.7812;
399343df4709Smrg                break;
399443df4709Smrg        default:
399543df4709Smrg                return;
399643df4709Smrg        }
399743df4709Smrg}
399843df4709Smrg
3999