radeon_video.c revision 40732134
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"
13209ff23fSmrg#include "radeon_macros.h"
14209ff23fSmrg#include "radeon_probe.h"
15209ff23fSmrg#include "radeon_video.h"
16209ff23fSmrg
17209ff23fSmrg#include "xf86.h"
18209ff23fSmrg#include "dixstruct.h"
19209ff23fSmrg#include "atipciids.h"
20209ff23fSmrg#include "xf86fbman.h"
21209ff23fSmrg
22209ff23fSmrg#include <X11/extensions/Xv.h>
23209ff23fSmrg#include "fourcc.h"
24209ff23fSmrg
25209ff23fSmrg#include "theatre_detect.h"
26209ff23fSmrg#include "theatre_reg.h"
27209ff23fSmrg#include "fi1236.h"
28209ff23fSmrg#include "msp3430.h"
29209ff23fSmrg#include "tda9885.h"
30209ff23fSmrg
31209ff23fSmrg#define OFF_DELAY       250  /* milliseconds */
32209ff23fSmrg#define FREE_DELAY      15000
33209ff23fSmrg
34209ff23fSmrg#define OFF_TIMER       0x01
35209ff23fSmrg#define FREE_TIMER      0x02
36209ff23fSmrg#define CLIENT_VIDEO_ON 0x04
37209ff23fSmrg
38209ff23fSmrg#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
39209ff23fSmrg
40209ff23fSmrg/* capture config constants */
41209ff23fSmrg#define BUF_TYPE_FIELD          0
42209ff23fSmrg#define BUF_TYPE_ALTERNATING    1
43209ff23fSmrg#define BUF_TYPE_FRAME          2
44209ff23fSmrg
45209ff23fSmrg
46209ff23fSmrg#define BUF_MODE_SINGLE         0
47209ff23fSmrg#define BUF_MODE_DOUBLE         1
48209ff23fSmrg#define BUF_MODE_TRIPLE         2
49209ff23fSmrg/* CAP0_CONFIG values */
50209ff23fSmrg
51209ff23fSmrg#define FORMAT_BROOKTREE        0
52209ff23fSmrg#define FORMAT_CCIR656          1
53209ff23fSmrg#define FORMAT_ZV               2
54209ff23fSmrg#define FORMAT_VIP16            3
55209ff23fSmrg#define FORMAT_TRANSPORT        4
56209ff23fSmrg
57209ff23fSmrg#define ENABLE_RADEON_CAPTURE_WEAVE (RADEON_CAP0_CONFIG_CONTINUOS \
58209ff23fSmrg                        | (BUF_MODE_DOUBLE <<7) \
59209ff23fSmrg                        | (BUF_TYPE_FRAME << 4) \
60209ff23fSmrg                        | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
61209ff23fSmrg                        | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
62209ff23fSmrg                        | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
63209ff23fSmrg                        | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
64209ff23fSmrg
65209ff23fSmrg#define ENABLE_RADEON_CAPTURE_BOB (RADEON_CAP0_CONFIG_CONTINUOS \
66209ff23fSmrg                        | (BUF_MODE_SINGLE <<7)  \
67209ff23fSmrg                        | (BUF_TYPE_ALTERNATING << 4) \
68209ff23fSmrg                        | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
69209ff23fSmrg                        | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
70209ff23fSmrg                        | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
71209ff23fSmrg                        | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
72209ff23fSmrg
73209ff23fSmrg
74209ff23fSmrgstatic void RADEONInitOffscreenImages(ScreenPtr);
75209ff23fSmrg
76209ff23fSmrgstatic XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr);
77209ff23fSmrgstatic int  RADEONPutImage(ScrnInfoPtr, short, short, short, short, short,
78209ff23fSmrg			short, short, short, int, unsigned char*, short,
79209ff23fSmrg			short, Bool, RegionPtr, pointer,
80209ff23fSmrg			DrawablePtr);
81209ff23fSmrgstatic void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
82209ff23fSmrgstatic int RADEONPutVideo(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y,
83209ff23fSmrg                        short src_w, short src_h, short drw_w, short drw_h,
84209ff23fSmrg			RegionPtr clipBoxes, pointer data, DrawablePtr pDraw);
85209ff23fSmrg
86209ff23fSmrgstatic void RADEON_board_setmisc(RADEONPortPrivPtr pPriv);
87209ff23fSmrgstatic void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
88209ff23fSmrgstatic void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv);
89209ff23fSmrgstatic void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv);
90209ff23fSmrgstatic void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv);
91209ff23fSmrg
92209ff23fSmrgstatic Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
93209ff23fSmrgstatic Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
94209ff23fSmrgstatic Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
95209ff23fSmrgstatic Atom xvGamma, xvColorspace;
96209ff23fSmrgstatic Atom xvCRTC;
97209ff23fSmrgstatic Atom xvEncoding, xvFrequency, xvVolume, xvMute,
98209ff23fSmrg	     xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
99209ff23fSmrg	     xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
100209ff23fSmrg	     xvLocationID, xvDeviceID, xvInstanceID, xvDumpStatus,
101209ff23fSmrg	     xvAdjustment;
102209ff23fSmrg
103209ff23fSmrgstatic Atom xvOvAlpha, xvGrAlpha, xvAlphaMode;
104209ff23fSmrg
105209ff23fSmrg#define GET_PORT_PRIVATE(pScrn) \
106209ff23fSmrg   (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
107209ff23fSmrg
108209ff23fSmrgstatic void
109209ff23fSmrgradeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
110209ff23fSmrg{
111209ff23fSmrg    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
112209ff23fSmrg    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
113209ff23fSmrg    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
114209ff23fSmrg    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
115209ff23fSmrg
116209ff23fSmrg    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
117209ff23fSmrg	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
118209ff23fSmrg}
119209ff23fSmrg
120209ff23fSmrgstatic void
121209ff23fSmrgradeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
122209ff23fSmrg{
123209ff23fSmrg    if (crtc->enabled) {
124209ff23fSmrg	crtc_box->x1 = crtc->x;
125209ff23fSmrg	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
126209ff23fSmrg	crtc_box->y1 = crtc->y;
127209ff23fSmrg	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
128209ff23fSmrg    } else
129209ff23fSmrg	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
130209ff23fSmrg}
131209ff23fSmrg
132209ff23fSmrgstatic int
133209ff23fSmrgradeon_box_area(BoxPtr box)
134209ff23fSmrg{
135209ff23fSmrg    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
136209ff23fSmrg}
137209ff23fSmrg
138b7e1c893Smrgxf86CrtcPtr
139ad43ddacSmrgradeon_pick_best_crtc(ScrnInfoPtr pScrn,
140ad43ddacSmrg		      int x1, int x2, int y1, int y2)
141b7e1c893Smrg{
142b7e1c893Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
143b7e1c893Smrg    int			coverage, best_coverage, c;
144b7e1c893Smrg    BoxRec		box, crtc_box, cover_box;
14540732134Srjs    RROutputPtr         primary_output = NULL;
14640732134Srjs    xf86CrtcPtr         best_crtc = NULL, primary_crtc = NULL;
147b7e1c893Smrg
148b7e1c893Smrg    box.x1 = x1;
149b7e1c893Smrg    box.x2 = x2;
150b7e1c893Smrg    box.y1 = y1;
151b7e1c893Smrg    box.y2 = y2;
152b7e1c893Smrg    best_coverage = 0;
15340732134Srjs
15440732134Srjs    /* Prefer the CRTC of the primary output */
15540732134Srjs    if (dixPrivateKeyRegistered(rrPrivKey)) {
15640732134Srjs	primary_output = RRFirstOutput(pScrn->pScreen);
15740732134Srjs    }
15840732134Srjs    if (primary_output && primary_output->crtc)
15940732134Srjs	primary_crtc = primary_output->crtc->devPrivate;
16040732134Srjs
161b7e1c893Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
162b7e1c893Smrg	xf86CrtcPtr crtc = xf86_config->crtc[c];
163b7e1c893Smrg	radeon_crtc_box(crtc, &crtc_box);
164b7e1c893Smrg	radeon_box_intersect(&cover_box, &crtc_box, &box);
165b7e1c893Smrg	coverage = radeon_box_area(&cover_box);
16640732134Srjs	if (coverage > best_coverage ||
16740732134Srjs	    (coverage == best_coverage && crtc == primary_crtc)) {
168b7e1c893Smrg	    best_crtc = crtc;
169b7e1c893Smrg	    best_coverage = coverage;
170b7e1c893Smrg	}
171b7e1c893Smrg    }
172b7e1c893Smrg    return best_crtc;
173b7e1c893Smrg}
174b7e1c893Smrg
175b7e1c893Smrg#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
176209ff23fSmrgstatic xf86CrtcPtr
177209ff23fSmrgradeon_covering_crtc(ScrnInfoPtr pScrn,
178209ff23fSmrg		     BoxPtr	box,
179209ff23fSmrg		     xf86CrtcPtr desired,
180209ff23fSmrg		     BoxPtr	crtc_box_ret)
181209ff23fSmrg{
182209ff23fSmrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
183209ff23fSmrg    xf86CrtcPtr		crtc, best_crtc;
184209ff23fSmrg    int			coverage, best_coverage;
185209ff23fSmrg    int			c;
186209ff23fSmrg    BoxRec		crtc_box, cover_box;
187209ff23fSmrg
188209ff23fSmrg    best_crtc = NULL;
189209ff23fSmrg    best_coverage = 0;
190209ff23fSmrg    crtc_box_ret->x1 = 0;
191209ff23fSmrg    crtc_box_ret->x2 = 0;
192209ff23fSmrg    crtc_box_ret->y1 = 0;
193209ff23fSmrg    crtc_box_ret->y2 = 0;
194209ff23fSmrg    for (c = 0; c < xf86_config->num_crtc; c++) {
195209ff23fSmrg	crtc = xf86_config->crtc[c];
196209ff23fSmrg	radeon_crtc_box(crtc, &crtc_box);
197209ff23fSmrg	radeon_box_intersect(&cover_box, &crtc_box, box);
198209ff23fSmrg	coverage = radeon_box_area(&cover_box);
199209ff23fSmrg	if (coverage && crtc == desired) {
200209ff23fSmrg	    *crtc_box_ret = crtc_box;
201209ff23fSmrg	    return crtc;
202209ff23fSmrg	} else if (coverage > best_coverage) {
203209ff23fSmrg	    *crtc_box_ret = crtc_box;
204209ff23fSmrg	    best_crtc = crtc;
205209ff23fSmrg	    best_coverage = coverage;
206209ff23fSmrg	}
207209ff23fSmrg    }
208209ff23fSmrg    return best_crtc;
209209ff23fSmrg}
210209ff23fSmrg
211209ff23fSmrgstatic Bool
212209ff23fSmrgradeon_crtc_clip_video_helper(ScrnInfoPtr pScrn,
213209ff23fSmrg			      xf86CrtcPtr *crtc_ret,
214209ff23fSmrg			      xf86CrtcPtr desired_crtc,
215209ff23fSmrg			      BoxPtr      dst,
216209ff23fSmrg			      INT32	  *xa,
217209ff23fSmrg			      INT32	  *xb,
218209ff23fSmrg			      INT32	  *ya,
219209ff23fSmrg			      INT32	  *yb,
220209ff23fSmrg			      RegionPtr   reg,
221209ff23fSmrg			      INT32	  width,
222209ff23fSmrg			      INT32	  height)
223209ff23fSmrg{
224209ff23fSmrg    Bool	ret;
225209ff23fSmrg    RegionRec	crtc_region_local;
226209ff23fSmrg    RegionPtr	crtc_region = reg;
227209ff23fSmrg
228209ff23fSmrg    /*
229209ff23fSmrg     * For overlay video, compute the relevant CRTC and
230209ff23fSmrg     * clip video to that
231209ff23fSmrg     */
232209ff23fSmrg    if (crtc_ret) {
233209ff23fSmrg	BoxRec		crtc_box;
234209ff23fSmrg	xf86CrtcPtr	crtc = radeon_covering_crtc(pScrn, dst,
235209ff23fSmrg						    desired_crtc,
236209ff23fSmrg						    &crtc_box);
237209ff23fSmrg
238209ff23fSmrg	if (crtc) {
239209ff23fSmrg	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
240209ff23fSmrg	    crtc_region = &crtc_region_local;
241209ff23fSmrg	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
242209ff23fSmrg	}
243209ff23fSmrg	*crtc_ret = crtc;
244209ff23fSmrg    }
245209ff23fSmrg
246209ff23fSmrg    ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb,
247209ff23fSmrg				crtc_region, width, height);
248209ff23fSmrg
249209ff23fSmrg    if (crtc_region != reg)
250209ff23fSmrg	REGION_UNINIT (pScreen, &crtc_region_local);
251209ff23fSmrg
252209ff23fSmrg    return ret;
253209ff23fSmrg}
254209ff23fSmrg#endif
255209ff23fSmrg
256209ff23fSmrgstatic Bool
257209ff23fSmrgradeon_crtc_clip_video(ScrnInfoPtr pScrn,
258209ff23fSmrg		       xf86CrtcPtr *crtc_ret,
259209ff23fSmrg		       xf86CrtcPtr desired_crtc,
260209ff23fSmrg		       BoxPtr      dst,
261209ff23fSmrg		       INT32       *xa,
262209ff23fSmrg		       INT32       *xb,
263209ff23fSmrg		       INT32       *ya,
264209ff23fSmrg		       INT32       *yb,
265209ff23fSmrg		       RegionPtr   reg,
266209ff23fSmrg		       INT32       width,
267209ff23fSmrg		       INT32       height)
268209ff23fSmrg{
269209ff23fSmrg#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER
270209ff23fSmrg    return radeon_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
271209ff23fSmrg				       dst, xa, xb, ya, yb,
272209ff23fSmrg				       reg, width, height);
273209ff23fSmrg#else
274209ff23fSmrg    return xf86_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc,
275209ff23fSmrg				       dst, xa, xb, ya, yb,
276209ff23fSmrg				       reg, width, height);
277209ff23fSmrg#endif
278209ff23fSmrg}
279209ff23fSmrg
280209ff23fSmrgvoid RADEONInitVideo(ScreenPtr pScreen)
281209ff23fSmrg{
282209ff23fSmrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
283209ff23fSmrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
2842f39173dSmrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
285209ff23fSmrg    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
286209ff23fSmrg    XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
287209ff23fSmrg    int num_adaptors;
288209ff23fSmrg
2892f39173dSmrg    /* no overlay or 3D on RN50 */
2902f39173dSmrg    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2)
2912f39173dSmrg	    return;
292209ff23fSmrg
293209ff23fSmrg    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
2942f39173dSmrg    newAdaptors = malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
295209ff23fSmrg    if (newAdaptors == NULL)
296209ff23fSmrg	return;
297209ff23fSmrg
298209ff23fSmrg    memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
299209ff23fSmrg    adaptors = newAdaptors;
300209ff23fSmrg
301ad43ddacSmrg    if (!IS_AVIVO_VARIANT && !info->kms_enabled) {
302209ff23fSmrg	overlayAdaptor = RADEONSetupImageVideo(pScreen);
303209ff23fSmrg	if (overlayAdaptor != NULL) {
304209ff23fSmrg	    adaptors[num_adaptors++] = overlayAdaptor;
305209ff23fSmrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
306209ff23fSmrg	} else
307209ff23fSmrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up overlay video\n");
308209ff23fSmrg	RADEONInitOffscreenImages(pScreen);
309209ff23fSmrg    }
310209ff23fSmrg
311b7e1c893Smrg    if ((info->ChipFamily < CHIP_FAMILY_RS400)
312209ff23fSmrg#ifdef XF86DRI
313b7e1c893Smrg	|| (info->directRenderingEnabled)
314209ff23fSmrg#endif
315b7e1c893Smrg	) {
316b7e1c893Smrg	texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen);
317b7e1c893Smrg	if (texturedAdaptor != NULL) {
318b7e1c893Smrg	    adaptors[num_adaptors++] = texturedAdaptor;
319b7e1c893Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
320209ff23fSmrg	} else
321b7e1c893Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up textured video\n");
322209ff23fSmrg    } else
323b7e1c893Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video requires CP on R5xx/R6xx/R7xx/IGP\n");
324209ff23fSmrg
325209ff23fSmrg    if(num_adaptors)
326209ff23fSmrg	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
327209ff23fSmrg
32840732134Srjs    if(texturedAdaptor) {
32940732134Srjs	XF86MCAdaptorPtr xvmcAdaptor = RADEONCreateAdaptorXvMC(pScreen, texturedAdaptor->name);
33040732134Srjs	if(xvmcAdaptor) {
33140732134Srjs	    if(!xf86XvMCScreenInit(pScreen, 1, &xvmcAdaptor))
33240732134Srjs		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] Failed to initialize extension.\n");
33340732134Srjs	    else
33440732134Srjs		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Extension initialized.\n");
33540732134Srjs	}
33640732134Srjs    }
33740732134Srjs
338209ff23fSmrg    if(newAdaptors)
3392f39173dSmrg	free(newAdaptors);
340209ff23fSmrg
341209ff23fSmrg}
342209ff23fSmrg
343209ff23fSmrg/* client libraries expect an encoding */
344209ff23fSmrgstatic XF86VideoEncodingRec DummyEncoding =
345209ff23fSmrg{
346209ff23fSmrg   0,
347209ff23fSmrg   "XV_IMAGE",
348921a55d8Smrg   2047, 2047,
349209ff23fSmrg   {1, 1}
350209ff23fSmrg};
351209ff23fSmrg
352209ff23fSmrg /* the picture is interlaced - hence the half-heights */
353209ff23fSmrg
354209ff23fSmrgstatic XF86VideoEncodingRec
355209ff23fSmrgInputVideoEncodings[] =
356209ff23fSmrg{
357921a55d8Smrg    { 0, "XV_IMAGE",			2047,2047,{1,1}},
358209ff23fSmrg    { 1, "pal-composite",		720, 288, { 1, 50 }},
359209ff23fSmrg    { 2, "pal-tuner",			720, 288, { 1, 50 }},
360209ff23fSmrg    { 3, "pal-svideo",			720, 288, { 1, 50 }},
361209ff23fSmrg    { 4, "ntsc-composite",		640, 240, { 1001, 60000 }},
362209ff23fSmrg    { 5, "ntsc-tuner",			640, 240, { 1001, 60000 }},
363209ff23fSmrg    { 6, "ntsc-svideo",			640, 240, { 1001, 60000 }},
364209ff23fSmrg    { 7, "secam-composite",		720, 288, { 1, 50 }},
365209ff23fSmrg    { 8, "secam-tuner",			720, 288, { 1, 50 }},
366209ff23fSmrg    { 9, "secam-svideo",		720, 288, { 1, 50 }},
367209ff23fSmrg    { 10,"pal_60-composite",		768, 288, { 1, 50 }},
368209ff23fSmrg    { 11,"pal_60-tuner",		768, 288, { 1, 50 }},
369209ff23fSmrg    { 12,"pal_60-svideo",		768, 288, { 1, 50 }}
370209ff23fSmrg};
371209ff23fSmrg
372209ff23fSmrg
373209ff23fSmrg#define NUM_FORMATS 12
374209ff23fSmrg
375209ff23fSmrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] =
376209ff23fSmrg{
377209ff23fSmrg   {8, TrueColor}, {8, DirectColor}, {8, PseudoColor},
378209ff23fSmrg   {8, GrayScale}, {8, StaticGray}, {8, StaticColor},
379209ff23fSmrg   {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
380209ff23fSmrg   {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
381209ff23fSmrg};
382209ff23fSmrg
383209ff23fSmrg
384209ff23fSmrg#if 0
385209ff23fSmrg#define NUM_ATTRIBUTES 9+6
386209ff23fSmrg
387209ff23fSmrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
388209ff23fSmrg{
389209ff23fSmrg   {XvSettable             ,     0,    1, "XV_SET_DEFAULTS"},
390209ff23fSmrg   {XvSettable | XvGettable,     0,    1, "XV_AUTOPAINT_COLORKEY"},
391209ff23fSmrg   {XvSettable | XvGettable,     0,   ~0, "XV_COLORKEY"},
392209ff23fSmrg   {XvSettable | XvGettable,     0,    1, "XV_DOUBLE_BUFFER"},
393209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
394209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
395209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
396209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
397209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
398209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
399209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
400209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
401209ff23fSmrg   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
402209ff23fSmrg   {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
403209ff23fSmrg   {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
404209ff23fSmrg};
405209ff23fSmrg
406209ff23fSmrg#endif
407209ff23fSmrg
408209ff23fSmrg#define NUM_ATTRIBUTES 22
409209ff23fSmrg#define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12)
410209ff23fSmrg
411209ff23fSmrgstatic XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] =
412209ff23fSmrg{
413209ff23fSmrg   {             XvGettable, 0, ~0, "XV_DEVICE_ID"},
414209ff23fSmrg   {             XvGettable, 0, ~0, "XV_LOCATION_ID"},
415209ff23fSmrg   {             XvGettable, 0, ~0, "XV_INSTANCE_ID"},
416209ff23fSmrg   {XvSettable		   , 0, 1, "XV_DUMP_STATUS"},
417209ff23fSmrg   {XvSettable             , 0, 1, "XV_SET_DEFAULTS"},
418209ff23fSmrg   {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
419209ff23fSmrg   {XvSettable | XvGettable, 0, ~0,"XV_COLORKEY"},
420209ff23fSmrg   {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
421209ff23fSmrg   {XvSettable | XvGettable,     0,  255, "XV_OVERLAY_ALPHA"},
422209ff23fSmrg   {XvSettable | XvGettable,     0,  255, "XV_GRAPHICS_ALPHA"},
423209ff23fSmrg   {XvSettable | XvGettable,     0,    1, "XV_ALPHA_MODE"},
424209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
425209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
426209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
427209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
428209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
429209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
430209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
431209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
432209ff23fSmrg   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
433209ff23fSmrg   {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
434209ff23fSmrg   {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
435209ff23fSmrg
436209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_BRIGHTNESS"},
437209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_CONTRAST"},
438209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_SATURATION"},
439209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_DEC_HUE"},
440209ff23fSmrg   {XvSettable | XvGettable, 0, 2, "XV_OVERLAY_DEINTERLACING_METHOD"},
441209ff23fSmrg   {XvSettable | XvGettable, 0, 12, "XV_ENCODING"},
442209ff23fSmrg   {XvSettable | XvGettable, 0, -1, "XV_FREQ"},
443209ff23fSmrg   {             XvGettable, -1000, 1000, "XV_TUNER_STATUS"},
444209ff23fSmrg   {XvSettable | XvGettable, -1000, 1000, "XV_VOLUME"},
445209ff23fSmrg   {XvSettable | XvGettable, 0, 1, "XV_MUTE"},
446209ff23fSmrg   {XvSettable | XvGettable, 0, 1, "XV_SAP"},
447209ff23fSmrg   {XvSettable | XvGettable, 0, 0x1F, "XV_DEBUG_ADJUSTMENT"},
448209ff23fSmrg   { 0, 0, 0, NULL}  /* just a place holder so I don't have to be fancy with commas */
449209ff23fSmrg};
450209ff23fSmrg
451209ff23fSmrg
452209ff23fSmrg#define INCLUDE_RGB_FORMATS 1
453209ff23fSmrg
454209ff23fSmrg#if INCLUDE_RGB_FORMATS
455209ff23fSmrg
456209ff23fSmrg#define NUM_IMAGES 8
457209ff23fSmrg
458209ff23fSmrg/* Note: GUIDs are bogus... - but nothing uses them anyway */
459209ff23fSmrg
460209ff23fSmrg#define FOURCC_RGBA32   0x41424752
461209ff23fSmrg
462209ff23fSmrg#define XVIMAGE_RGBA32(byte_order)   \
463209ff23fSmrg        { \
464209ff23fSmrg                FOURCC_RGBA32, \
465209ff23fSmrg                XvRGB, \
466209ff23fSmrg                byte_order, \
467209ff23fSmrg                { 'R', 'G', 'B', 'A', \
468209ff23fSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
469209ff23fSmrg                32, \
470209ff23fSmrg                XvPacked, \
471209ff23fSmrg                1, \
472209ff23fSmrg                32, 0x00FF0000, 0x0000FF00, 0x000000FF, \
473209ff23fSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
474209ff23fSmrg                {'A', 'R', 'G', 'B', \
475209ff23fSmrg                  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}, \
476209ff23fSmrg                XvTopToBottom \
477209ff23fSmrg        }
478209ff23fSmrg
479209ff23fSmrg#define FOURCC_RGB24    0x00000000
480209ff23fSmrg
481209ff23fSmrg#define XVIMAGE_RGB24   \
482209ff23fSmrg        { \
483209ff23fSmrg                FOURCC_RGB24, \
484209ff23fSmrg                XvRGB, \
485209ff23fSmrg                LSBFirst, \
486209ff23fSmrg                { 'R', 'G', 'B', 0, \
487209ff23fSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
488209ff23fSmrg                24, \
489209ff23fSmrg                XvPacked, \
490209ff23fSmrg                1, \
491209ff23fSmrg                24, 0x00FF0000, 0x0000FF00, 0x000000FF, \
492209ff23fSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
493209ff23fSmrg                { 'R', 'G', 'B', \
494209ff23fSmrg                  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}, \
495209ff23fSmrg                XvTopToBottom \
496209ff23fSmrg        }
497209ff23fSmrg
498209ff23fSmrg#define FOURCC_RGBT16   0x54424752
499209ff23fSmrg
500209ff23fSmrg#define XVIMAGE_RGBT16(byte_order)   \
501209ff23fSmrg        { \
502209ff23fSmrg                FOURCC_RGBT16, \
503209ff23fSmrg                XvRGB, \
504209ff23fSmrg                byte_order, \
505209ff23fSmrg                { 'R', 'G', 'B', 'T', \
506209ff23fSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
507209ff23fSmrg                16, \
508209ff23fSmrg                XvPacked, \
509209ff23fSmrg                1, \
510209ff23fSmrg                16, 0x00007C00, 0x000003E0, 0x0000001F, \
511209ff23fSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
512209ff23fSmrg                {'A', 'R', 'G', 'B', \
513209ff23fSmrg                  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}, \
514209ff23fSmrg                XvTopToBottom \
515209ff23fSmrg        }
516209ff23fSmrg
517209ff23fSmrg#define FOURCC_RGB16    0x32424752
518209ff23fSmrg
519209ff23fSmrg#define XVIMAGE_RGB16(byte_order)   \
520209ff23fSmrg        { \
521209ff23fSmrg                FOURCC_RGB16, \
522209ff23fSmrg                XvRGB, \
523209ff23fSmrg                byte_order, \
524209ff23fSmrg                { 'R', 'G', 'B', 0x00, \
525209ff23fSmrg                  0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
526209ff23fSmrg                16, \
527209ff23fSmrg                XvPacked, \
528209ff23fSmrg                1, \
529209ff23fSmrg                16, 0x0000F800, 0x000007E0, 0x0000001F, \
530209ff23fSmrg                0, 0, 0, 0, 0, 0, 0, 0, 0, \
531209ff23fSmrg                {'R', 'G', 'B', \
532209ff23fSmrg                  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}, \
533209ff23fSmrg                XvTopToBottom \
534209ff23fSmrg        }
535209ff23fSmrg
536209ff23fSmrgstatic XF86ImageRec Images[NUM_IMAGES] =
537209ff23fSmrg{
538209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
539209ff23fSmrg        XVIMAGE_RGBA32(MSBFirst),
540209ff23fSmrg        XVIMAGE_RGBT16(MSBFirst),
541209ff23fSmrg        XVIMAGE_RGB16(MSBFirst),
542209ff23fSmrg#else
543209ff23fSmrg        XVIMAGE_RGBA32(LSBFirst),
544209ff23fSmrg        XVIMAGE_RGBT16(LSBFirst),
545209ff23fSmrg        XVIMAGE_RGB16(LSBFirst),
546209ff23fSmrg#endif
547209ff23fSmrg        XVIMAGE_RGB24,
548209ff23fSmrg        XVIMAGE_YUY2,
549209ff23fSmrg        XVIMAGE_UYVY,
550209ff23fSmrg        XVIMAGE_YV12,
551209ff23fSmrg        XVIMAGE_I420
552209ff23fSmrg};
553209ff23fSmrg
554209ff23fSmrg#else
555209ff23fSmrg
556209ff23fSmrg#define NUM_IMAGES 4
557209ff23fSmrg
558209ff23fSmrgstatic XF86ImageRec Images[NUM_IMAGES] =
559209ff23fSmrg{
560209ff23fSmrg    XVIMAGE_YUY2,
561209ff23fSmrg    XVIMAGE_UYVY,
562209ff23fSmrg    XVIMAGE_YV12,
563209ff23fSmrg    XVIMAGE_I420
564209ff23fSmrg};
565209ff23fSmrg
566209ff23fSmrg#endif
567209ff23fSmrg
568209ff23fSmrg/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
569209ff23fSmrgstatic REF_TRANSFORM trans[2] =
570209ff23fSmrg{
571209ff23fSmrg    {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
572209ff23fSmrg    {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0}  /* BT.709 */
573209ff23fSmrg};
574209ff23fSmrg
575209ff23fSmrg/* Gamma curve definition for preset gammas */
576209ff23fSmrgtypedef struct tagGAMMA_CURVE_R100
577209ff23fSmrg{
578209ff23fSmrg    uint32_t GAMMA_0_F_SLOPE;
579209ff23fSmrg    uint32_t GAMMA_0_F_OFFSET;
580209ff23fSmrg    uint32_t GAMMA_10_1F_SLOPE;
581209ff23fSmrg    uint32_t GAMMA_10_1F_OFFSET;
582209ff23fSmrg    uint32_t GAMMA_20_3F_SLOPE;
583209ff23fSmrg    uint32_t GAMMA_20_3F_OFFSET;
584209ff23fSmrg    uint32_t GAMMA_40_7F_SLOPE;
585209ff23fSmrg    uint32_t GAMMA_40_7F_OFFSET;
586209ff23fSmrg    uint32_t GAMMA_380_3BF_SLOPE;
587209ff23fSmrg    uint32_t GAMMA_380_3BF_OFFSET;
588209ff23fSmrg    uint32_t GAMMA_3C0_3FF_SLOPE;
589209ff23fSmrg    uint32_t GAMMA_3C0_3FF_OFFSET;
590209ff23fSmrg    float OvGammaCont;
591209ff23fSmrg} GAMMA_CURVE_R100;
592209ff23fSmrg
593209ff23fSmrgtypedef struct tagGAMMA_CURVE_R200
594209ff23fSmrg{
595209ff23fSmrg    uint32_t GAMMA_0_F_SLOPE;
596209ff23fSmrg    uint32_t GAMMA_0_F_OFFSET;
597209ff23fSmrg    uint32_t GAMMA_10_1F_SLOPE;
598209ff23fSmrg    uint32_t GAMMA_10_1F_OFFSET;
599209ff23fSmrg    uint32_t GAMMA_20_3F_SLOPE;
600209ff23fSmrg    uint32_t GAMMA_20_3F_OFFSET;
601209ff23fSmrg    uint32_t GAMMA_40_7F_SLOPE;
602209ff23fSmrg    uint32_t GAMMA_40_7F_OFFSET;
603209ff23fSmrg    uint32_t GAMMA_80_BF_SLOPE;
604209ff23fSmrg    uint32_t GAMMA_80_BF_OFFSET;
605209ff23fSmrg    uint32_t GAMMA_C0_FF_SLOPE;
606209ff23fSmrg    uint32_t GAMMA_C0_FF_OFFSET;
607209ff23fSmrg    uint32_t GAMMA_100_13F_SLOPE;
608209ff23fSmrg    uint32_t GAMMA_100_13F_OFFSET;
609209ff23fSmrg    uint32_t GAMMA_140_17F_SLOPE;
610209ff23fSmrg    uint32_t GAMMA_140_17F_OFFSET;
611209ff23fSmrg    uint32_t GAMMA_180_1BF_SLOPE;
612209ff23fSmrg    uint32_t GAMMA_180_1BF_OFFSET;
613209ff23fSmrg    uint32_t GAMMA_1C0_1FF_SLOPE;
614209ff23fSmrg    uint32_t GAMMA_1C0_1FF_OFFSET;
615209ff23fSmrg    uint32_t GAMMA_200_23F_SLOPE;
616209ff23fSmrg    uint32_t GAMMA_200_23F_OFFSET;
617209ff23fSmrg    uint32_t GAMMA_240_27F_SLOPE;
618209ff23fSmrg    uint32_t GAMMA_240_27F_OFFSET;
619209ff23fSmrg    uint32_t GAMMA_280_2BF_SLOPE;
620209ff23fSmrg    uint32_t GAMMA_280_2BF_OFFSET;
621209ff23fSmrg    uint32_t GAMMA_2C0_2FF_SLOPE;
622209ff23fSmrg    uint32_t GAMMA_2C0_2FF_OFFSET;
623209ff23fSmrg    uint32_t GAMMA_300_33F_SLOPE;
624209ff23fSmrg    uint32_t GAMMA_300_33F_OFFSET;
625209ff23fSmrg    uint32_t GAMMA_340_37F_SLOPE;
626209ff23fSmrg    uint32_t GAMMA_340_37F_OFFSET;
627209ff23fSmrg    uint32_t GAMMA_380_3BF_SLOPE;
628209ff23fSmrg    uint32_t GAMMA_380_3BF_OFFSET;
629209ff23fSmrg    uint32_t GAMMA_3C0_3FF_SLOPE;
630209ff23fSmrg    uint32_t GAMMA_3C0_3FF_OFFSET;
631209ff23fSmrg    float OvGammaCont;
632209ff23fSmrg} GAMMA_CURVE_R200;
633209ff23fSmrg
634209ff23fSmrg
635209ff23fSmrg/* Preset gammas */
636209ff23fSmrgstatic GAMMA_CURVE_R100 gamma_curve_r100[8] =
637209ff23fSmrg{
638209ff23fSmrg	/* Gamma 1.0 */
639209ff23fSmrg	{0x100, 0x0,
640209ff23fSmrg	 0x100, 0x20,
641209ff23fSmrg	 0x100, 0x40,
642209ff23fSmrg	 0x100, 0x80,
643209ff23fSmrg	 0x100, 0x100,
644209ff23fSmrg	 0x100, 0x100,
645209ff23fSmrg	 1.0},
646209ff23fSmrg	/* Gamma 0.85 */
647209ff23fSmrg	{0x75,  0x0,
648209ff23fSmrg	 0xA2,  0xF,
649209ff23fSmrg	 0xAC,  0x23,
650209ff23fSmrg	 0xC6,  0x4E,
651209ff23fSmrg	 0x129, 0xD6,
652209ff23fSmrg	 0x12B, 0xD5,
653209ff23fSmrg	 1.0},
654209ff23fSmrg	/* Gamma 1.1 */
655209ff23fSmrg	{0x180, 0x0,
656209ff23fSmrg	 0x13C, 0x30,
657209ff23fSmrg	 0x13C, 0x57,
658209ff23fSmrg	 0x123, 0xA5,
659209ff23fSmrg	 0xEA,  0x116,
660209ff23fSmrg	 0xEA, 0x116,
661209ff23fSmrg	 0.9913},
662209ff23fSmrg	/* Gamma 1.2 */
663209ff23fSmrg	{0x21B, 0x0,
664209ff23fSmrg	 0x16D, 0x43,
665209ff23fSmrg	 0x172, 0x71,
666209ff23fSmrg	 0x13D, 0xCD,
667209ff23fSmrg	 0xD9,  0x128,
668209ff23fSmrg	 0xD6, 0x12A,
669209ff23fSmrg	 0.9827},
670209ff23fSmrg	/* Gamma 1.45 */
671209ff23fSmrg	{0x404, 0x0,
672209ff23fSmrg	 0x1B9, 0x81,
673209ff23fSmrg	 0x1EE, 0xB8,
674209ff23fSmrg	 0x16A, 0x133,
675209ff23fSmrg	 0xB7, 0x14B,
676209ff23fSmrg	 0xB2, 0x14E,
677209ff23fSmrg	 0.9567},
678209ff23fSmrg	/* Gamma 1.7 */
679209ff23fSmrg	{0x658, 0x0,
680209ff23fSmrg	 0x1B5, 0xCB,
681209ff23fSmrg	 0x25F, 0x102,
682209ff23fSmrg	 0x181, 0x199,
683209ff23fSmrg	 0x9C,  0x165,
684209ff23fSmrg	 0x98, 0x167,
685209ff23fSmrg	 0.9394},
686209ff23fSmrg	/* Gamma 2.2 */
687209ff23fSmrg	{0x7FF, 0x0,
688209ff23fSmrg	 0x625, 0x100,
689209ff23fSmrg	 0x1E4, 0x1C4,
690209ff23fSmrg	 0x1BD, 0x23D,
691209ff23fSmrg	 0x79,  0x187,
692209ff23fSmrg	 0x76,  0x188,
693209ff23fSmrg	 0.9135},
694209ff23fSmrg	/* Gamma 2.5 */
695209ff23fSmrg	{0x7FF, 0x0,
696209ff23fSmrg	 0x7FF, 0x100,
697209ff23fSmrg	 0x2AD, 0x200,
698209ff23fSmrg	 0x1A2, 0x2AB,
699209ff23fSmrg	 0x6E,  0x194,
700209ff23fSmrg	 0x67,  0x197,
701209ff23fSmrg	 0.9135}
702209ff23fSmrg};
703209ff23fSmrg
704209ff23fSmrgstatic GAMMA_CURVE_R200 gamma_curve_r200[8] =
705209ff23fSmrg {
706209ff23fSmrg	/* Gamma 1.0 */
707209ff23fSmrg      {0x00000100, 0x00000000,
708209ff23fSmrg       0x00000100, 0x00000020,
709209ff23fSmrg       0x00000100, 0x00000040,
710209ff23fSmrg       0x00000100, 0x00000080,
711209ff23fSmrg       0x00000100, 0x00000100,
712209ff23fSmrg       0x00000100, 0x00000100,
713209ff23fSmrg       0x00000100, 0x00000200,
714209ff23fSmrg       0x00000100, 0x00000200,
715209ff23fSmrg       0x00000100, 0x00000300,
716209ff23fSmrg       0x00000100, 0x00000300,
717209ff23fSmrg       0x00000100, 0x00000400,
718209ff23fSmrg       0x00000100, 0x00000400,
719209ff23fSmrg       0x00000100, 0x00000500,
720209ff23fSmrg       0x00000100, 0x00000500,
721209ff23fSmrg       0x00000100, 0x00000600,
722209ff23fSmrg       0x00000100, 0x00000600,
723209ff23fSmrg       0x00000100, 0x00000700,
724209ff23fSmrg       0x00000100, 0x00000700,
725209ff23fSmrg       1.0},
726209ff23fSmrg	/* Gamma 0.85 */
727209ff23fSmrg      {0x0000001D, 0x00000000,
728209ff23fSmrg       0x00000028, 0x0000000F,
729209ff23fSmrg       0x00000056, 0x00000023,
730209ff23fSmrg       0x000000C5, 0x0000004E,
731209ff23fSmrg       0x000000DA, 0x000000B0,
732209ff23fSmrg       0x000000E6, 0x000000AA,
733209ff23fSmrg       0x000000F1, 0x00000190,
734209ff23fSmrg       0x000000F9, 0x0000018C,
735209ff23fSmrg       0x00000101, 0x00000286,
736209ff23fSmrg       0x00000108, 0x00000282,
737209ff23fSmrg       0x0000010D, 0x0000038A,
738209ff23fSmrg       0x00000113, 0x00000387,
739209ff23fSmrg       0x00000118, 0x0000049A,
740209ff23fSmrg       0x0000011C, 0x00000498,
741209ff23fSmrg       0x00000120, 0x000005B4,
742209ff23fSmrg       0x00000124, 0x000005B2,
743209ff23fSmrg       0x00000128, 0x000006D6,
744209ff23fSmrg       0x0000012C, 0x000006D5,
745209ff23fSmrg       1.0},
746209ff23fSmrg	/* Gamma 1.1 */
747209ff23fSmrg      {0x00000060, 0x00000000,
748209ff23fSmrg       0x0000004F, 0x00000030,
749209ff23fSmrg       0x0000009C, 0x00000057,
750209ff23fSmrg       0x00000121, 0x000000A5,
751209ff23fSmrg       0x00000113, 0x00000136,
752209ff23fSmrg       0x0000010B, 0x0000013A,
753209ff23fSmrg       0x00000105, 0x00000245,
754209ff23fSmrg       0x00000100, 0x00000247,
755209ff23fSmrg       0x000000FD, 0x00000348,
756209ff23fSmrg       0x000000F9, 0x00000349,
757209ff23fSmrg       0x000000F6, 0x00000443,
758209ff23fSmrg       0x000000F4, 0x00000444,
759209ff23fSmrg       0x000000F2, 0x00000538,
760209ff23fSmrg       0x000000F0, 0x00000539,
761209ff23fSmrg       0x000000EE, 0x00000629,
762209ff23fSmrg       0x000000EC, 0x00000629,
763209ff23fSmrg       0x000000EB, 0x00000716,
764209ff23fSmrg       0x000000E9, 0x00000717,
765209ff23fSmrg       0.9913},
766209ff23fSmrg	/* Gamma 1.2 */
767209ff23fSmrg      {0x00000087, 0x00000000,
768209ff23fSmrg       0x0000005B, 0x00000043,
769209ff23fSmrg       0x000000B7, 0x00000071,
770209ff23fSmrg       0x0000013D, 0x000000CD,
771209ff23fSmrg       0x00000121, 0x0000016B,
772209ff23fSmrg       0x00000113, 0x00000172,
773209ff23fSmrg       0x00000107, 0x00000286,
774209ff23fSmrg       0x000000FF, 0x0000028A,
775209ff23fSmrg       0x000000F8, 0x00000389,
776209ff23fSmrg       0x000000F2, 0x0000038B,
777209ff23fSmrg       0x000000ED, 0x0000047D,
778209ff23fSmrg       0x000000E9, 0x00000480,
779209ff23fSmrg       0x000000E5, 0x00000568,
780209ff23fSmrg       0x000000E1, 0x0000056A,
781209ff23fSmrg       0x000000DE, 0x0000064B,
782209ff23fSmrg       0x000000DB, 0x0000064D,
783209ff23fSmrg       0x000000D9, 0x00000728,
784209ff23fSmrg       0x000000D6, 0x00000729,
785209ff23fSmrg       0.9827},
786209ff23fSmrg	/* Gamma 1.45 */
787209ff23fSmrg      {0x00000101, 0x00000000,
788209ff23fSmrg       0x0000006E, 0x00000081,
789209ff23fSmrg       0x000000F7, 0x000000B8,
790209ff23fSmrg       0x0000016E, 0x00000133,
791209ff23fSmrg       0x00000139, 0x000001EA,
792209ff23fSmrg       0x0000011B, 0x000001F9,
793209ff23fSmrg       0x00000105, 0x00000314,
794209ff23fSmrg       0x000000F6, 0x0000031C,
795209ff23fSmrg       0x000000E9, 0x00000411,
796209ff23fSmrg       0x000000DF, 0x00000417,
797209ff23fSmrg       0x000000D7, 0x000004F6,
798209ff23fSmrg       0x000000CF, 0x000004F9,
799209ff23fSmrg       0x000000C9, 0x000005C9,
800209ff23fSmrg       0x000000C4, 0x000005CC,
801209ff23fSmrg       0x000000BF, 0x0000068F,
802209ff23fSmrg       0x000000BA, 0x00000691,
803209ff23fSmrg       0x000000B6, 0x0000074B,
804209ff23fSmrg       0x000000B2, 0x0000074D,
805209ff23fSmrg       0.9567},
806209ff23fSmrg	/* Gamma 1.7 */
807209ff23fSmrg      {0x00000196, 0x00000000,
808209ff23fSmrg       0x0000006D, 0x000000CB,
809209ff23fSmrg       0x0000012F, 0x00000102,
810209ff23fSmrg       0x00000187, 0x00000199,
811209ff23fSmrg       0x00000144, 0x0000025b,
812209ff23fSmrg       0x00000118, 0x00000273,
813209ff23fSmrg       0x000000FE, 0x0000038B,
814209ff23fSmrg       0x000000E9, 0x00000395,
815209ff23fSmrg       0x000000DA, 0x0000047E,
816209ff23fSmrg       0x000000CE, 0x00000485,
817209ff23fSmrg       0x000000C3, 0x00000552,
818209ff23fSmrg       0x000000BB, 0x00000556,
819209ff23fSmrg       0x000000B3, 0x00000611,
820209ff23fSmrg       0x000000AC, 0x00000614,
821209ff23fSmrg       0x000000A7, 0x000006C1,
822209ff23fSmrg       0x000000A1, 0x000006C3,
823209ff23fSmrg       0x0000009D, 0x00000765,
824209ff23fSmrg       0x00000098, 0x00000767,
825209ff23fSmrg       0.9394},
826209ff23fSmrg	/* Gamma 2.2 */
827209ff23fSmrg      {0x000001FF, 0x00000000,
828209ff23fSmrg       0x0000018A, 0x00000100,
829209ff23fSmrg       0x000000F1, 0x000001C5,
830209ff23fSmrg       0x000001D6, 0x0000023D,
831209ff23fSmrg       0x00000124, 0x00000328,
832209ff23fSmrg       0x00000116, 0x0000032F,
833209ff23fSmrg       0x000000E2, 0x00000446,
834209ff23fSmrg       0x000000D3, 0x0000044D,
835209ff23fSmrg       0x000000BC, 0x00000520,
836209ff23fSmrg       0x000000B0, 0x00000526,
837209ff23fSmrg       0x000000A4, 0x000005D6,
838209ff23fSmrg       0x0000009B, 0x000005DB,
839209ff23fSmrg       0x00000092, 0x00000676,
840209ff23fSmrg       0x0000008B, 0x00000679,
841209ff23fSmrg       0x00000085, 0x00000704,
842209ff23fSmrg       0x00000080, 0x00000707,
843209ff23fSmrg       0x0000007B, 0x00000787,
844209ff23fSmrg       0x00000076, 0x00000789,
845209ff23fSmrg       0.9135},
846209ff23fSmrg	/* Gamma 2.5 */
847209ff23fSmrg      {0x000001FF, 0x00000000,
848209ff23fSmrg       0x000001FF, 0x00000100,
849209ff23fSmrg       0x00000159, 0x000001FF,
850209ff23fSmrg       0x000001AC, 0x000002AB,
851209ff23fSmrg       0x0000012F, 0x00000381,
852209ff23fSmrg       0x00000101, 0x00000399,
853209ff23fSmrg       0x000000D9, 0x0000049A,
854209ff23fSmrg       0x000000C3, 0x000004A5,
855209ff23fSmrg       0x000000AF, 0x00000567,
856209ff23fSmrg       0x000000A1, 0x0000056E,
857209ff23fSmrg       0x00000095, 0x00000610,
858209ff23fSmrg       0x0000008C, 0x00000614,
859209ff23fSmrg       0x00000084, 0x000006A0,
860209ff23fSmrg       0x0000007D, 0x000006A4,
861209ff23fSmrg       0x00000077, 0x00000721,
862209ff23fSmrg       0x00000071, 0x00000723,
863209ff23fSmrg       0x0000006D, 0x00000795,
864209ff23fSmrg       0x00000068, 0x00000797,
865209ff23fSmrg       0.9135}
866209ff23fSmrg};
867209ff23fSmrg
868209ff23fSmrgstatic void
869209ff23fSmrgRADEONSetOverlayGamma(ScrnInfoPtr pScrn, uint32_t gamma)
870209ff23fSmrg{
871209ff23fSmrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
872209ff23fSmrg    unsigned char   *RADEONMMIO = info->MMIO;
873209ff23fSmrg
874209ff23fSmrg    /* Set gamma */
875209ff23fSmrg    RADEONWaitForIdleMMIO(pScrn);
876209ff23fSmrg
877209ff23fSmrg    if (info->ChipFamily < CHIP_FAMILY_R200) {
878209ff23fSmrg	uint32_t ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL) & ~RADEON_SCALER_GAMMA_SEL_MASK;
879209ff23fSmrg	OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 5));
880209ff23fSmrg    }
881209ff23fSmrg
882209ff23fSmrg    /* Load gamma curve adjustments */
883209ff23fSmrg    if (info->ChipFamily >= CHIP_FAMILY_R200) {
884209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_000_00F,
885209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
886209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010));
887209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_010_01F,
888209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
889209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
890209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_020_03F,
891209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
892209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
893209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_040_07F,
894209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
895209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
896209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_080_0BF,
897209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_80_BF_OFFSET << 0x00000000) |
898209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_80_BF_SLOPE << 0x00000010));
899209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_0C0_0FF,
900209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_C0_FF_OFFSET << 0x00000000) |
901209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_C0_FF_SLOPE << 0x00000010));
902209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_100_13F,
903209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_100_13F_OFFSET << 0x00000000) |
904209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_100_13F_SLOPE << 0x00000010));
905209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_140_17F,
906209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_140_17F_OFFSET << 0x00000000) |
907209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_140_17F_SLOPE << 0x00000010));
908209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_180_1BF,
909209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_180_1BF_OFFSET << 0x00000000) |
910209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_180_1BF_SLOPE << 0x00000010));
911209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_1C0_1FF,
912209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_OFFSET << 0x00000000) |
913209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_1C0_1FF_SLOPE << 0x00000010));
914209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_200_23F,
915209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_200_23F_OFFSET << 0x00000000) |
916209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_200_23F_SLOPE << 0x00000010));
917209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_240_27F,
918209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_240_27F_OFFSET << 0x00000000) |
919209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_240_27F_SLOPE << 0x00000010));
920209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_280_2BF,
921209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_280_2BF_OFFSET << 0x00000000) |
922209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_280_2BF_SLOPE << 0x00000010));
923209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_2C0_2FF,
924209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_OFFSET << 0x00000000) |
925209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_2C0_2FF_SLOPE << 0x00000010));
926209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_300_33F,
927209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_300_33F_OFFSET << 0x00000000) |
928209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_300_33F_SLOPE << 0x00000010));
929209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_340_37F,
930209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_340_37F_OFFSET << 0x00000000) |
931209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_340_37F_SLOPE << 0x00000010));
932209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_380_3BF,
933209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
934209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
935209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
936209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
937209ff23fSmrg	    (gamma_curve_r200[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
938209ff23fSmrg    } else {
939209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_000_00F,
940209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_0_F_OFFSET << 0x00000000) |
941209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_0_F_SLOPE << 0x00000010));
942209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_010_01F,
943209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_10_1F_OFFSET << 0x00000000) |
944209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_10_1F_SLOPE << 0x00000010));
945209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_020_03F,
946209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_20_3F_OFFSET << 0x00000000) |
947209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_20_3F_SLOPE << 0x00000010));
948209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_040_07F,
949209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_40_7F_OFFSET << 0x00000000) |
950209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_40_7F_SLOPE << 0x00000010));
951209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_380_3BF,
952209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) |
953209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_380_3BF_SLOPE << 0x00000010));
954209ff23fSmrg    	OUTREG(RADEON_OV0_GAMMA_3C0_3FF,
955209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) |
956209ff23fSmrg	    (gamma_curve_r100[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010));
957209ff23fSmrg    }
958209ff23fSmrg
959209ff23fSmrg}
960209ff23fSmrg
961209ff23fSmrgstatic uint32_t
962209ff23fSmrgRADEONTranslateUserGamma(uint32_t user_gamma)
963209ff23fSmrg{
964209ff23fSmrg    /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
965209ff23fSmrg    if (user_gamma <= 925)       /* 0.85 */
966209ff23fSmrg	return 1;
967209ff23fSmrg    else if (user_gamma <= 1050) /* 1.0  */
968209ff23fSmrg	return 0;
969209ff23fSmrg    else if (user_gamma <= 1150) /* 1.1  */
970209ff23fSmrg	return 2;
971209ff23fSmrg    else if (user_gamma <= 1325) /* 1.2  */
972209ff23fSmrg	return 3;
973209ff23fSmrg    else if (user_gamma <= 1575) /* 1.45 */
974209ff23fSmrg	return 4;
975209ff23fSmrg    else if (user_gamma <= 1950) /* 1.7  */
976209ff23fSmrg	return 5;
977209ff23fSmrg    else if (user_gamma <= 2350) /* 2.2  */
978209ff23fSmrg	return 6;
979209ff23fSmrg    else if (user_gamma > 2350)  /* 2.5  */
980209ff23fSmrg	return 7;
981209ff23fSmrg    else
982209ff23fSmrg	return 0;
983209ff23fSmrg}
984209ff23fSmrg
985209ff23fSmrg
986209ff23fSmrg/****************************************************************************
987209ff23fSmrg * SetTransform                                                             *
988209ff23fSmrg *  Function: Calculates and sets color space transform from supplied       *
989209ff23fSmrg *            reference transform, gamma, brightness, contrast, hue and     *
990209ff23fSmrg *            saturation.                                                   *
991209ff23fSmrg *    Inputs: bright - brightness                                           *
992209ff23fSmrg *            cont - contrast                                               *
993209ff23fSmrg *            sat - saturation                                              *
994209ff23fSmrg *            hue - hue                                                     *
995209ff23fSmrg *            red_intensity - intensity of red component                    *
996209ff23fSmrg *            green_intensity - intensity of green component                *
997209ff23fSmrg *            blue_intensity - intensity of blue component                  *
998209ff23fSmrg *            ref - index to the table of refernce transforms               *
999209ff23fSmrg *            user_gamma - gamma value x 1000 (e.g., 1200 = gamma of 1.2)   *
1000209ff23fSmrg *   Outputs: NONE                                                          *
1001209ff23fSmrg ****************************************************************************/
1002209ff23fSmrg
1003209ff23fSmrgstatic void RADEONSetTransform (ScrnInfoPtr pScrn,
1004209ff23fSmrg				float	    bright,
1005209ff23fSmrg				float	    cont,
1006209ff23fSmrg				float	    sat,
1007209ff23fSmrg				float	    hue,
1008209ff23fSmrg				float	    red_intensity,
1009209ff23fSmrg				float	    green_intensity,
1010209ff23fSmrg				float	    blue_intensity,
1011209ff23fSmrg				uint32_t    ref,
1012209ff23fSmrg				uint32_t    user_gamma)
1013209ff23fSmrg{
1014209ff23fSmrg    RADEONInfoPtr    info = RADEONPTR(pScrn);
1015209ff23fSmrg    unsigned char   *RADEONMMIO = info->MMIO;
1016209ff23fSmrg    float	    OvHueSin, OvHueCos;
1017209ff23fSmrg    float	    CAdjLuma, CAdjOff;
1018209ff23fSmrg    float	    CAdjRCb, CAdjRCr;
1019209ff23fSmrg    float	    CAdjGCb, CAdjGCr;
1020209ff23fSmrg    float	    CAdjBCb, CAdjBCr;
1021209ff23fSmrg    float	    RedAdj,GreenAdj,BlueAdj;
1022209ff23fSmrg    float	    OvLuma, OvROff, OvGOff, OvBOff;
1023209ff23fSmrg    float	    OvRCb, OvRCr;
1024209ff23fSmrg    float	    OvGCb, OvGCr;
1025209ff23fSmrg    float	    OvBCb, OvBCr;
1026209ff23fSmrg    float	    Loff = 64.0;
1027209ff23fSmrg    float	    Coff = 512.0f;
1028209ff23fSmrg
1029209ff23fSmrg    uint32_t	    dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff;
1030209ff23fSmrg    uint32_t	    dwOvRCb, dwOvRCr;
1031209ff23fSmrg    uint32_t	    dwOvGCb, dwOvGCr;
1032209ff23fSmrg    uint32_t	    dwOvBCb, dwOvBCr;
1033209ff23fSmrg    uint32_t	    gamma = 0;
1034209ff23fSmrg
1035209ff23fSmrg    if (ref >= 2)
1036209ff23fSmrg	return;
1037209ff23fSmrg
1038209ff23fSmrg    /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */
1039209ff23fSmrg    gamma = RADEONTranslateUserGamma(user_gamma);
1040209ff23fSmrg
1041209ff23fSmrg    if (gamma >= 8)
1042209ff23fSmrg	return;
1043209ff23fSmrg
1044209ff23fSmrg    OvHueSin = sin(hue);
1045209ff23fSmrg    OvHueCos = cos(hue);
1046209ff23fSmrg
1047209ff23fSmrg    CAdjLuma = cont * trans[ref].RefLuma;
1048209ff23fSmrg    CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0;
1049209ff23fSmrg    RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0;
1050209ff23fSmrg    GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0;
1051209ff23fSmrg    BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0;
1052209ff23fSmrg
1053209ff23fSmrg    CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr;
1054209ff23fSmrg    CAdjRCr = sat * OvHueCos * trans[ref].RefRCr;
1055209ff23fSmrg    CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr);
1056209ff23fSmrg    CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr);
1057209ff23fSmrg    CAdjBCb = sat * OvHueCos * trans[ref].RefBCb;
1058209ff23fSmrg    CAdjBCr = sat * OvHueSin * trans[ref].RefBCb;
1059209ff23fSmrg
1060209ff23fSmrg#if 0 /* default constants */
1061209ff23fSmrg    CAdjLuma = 1.16455078125;
1062209ff23fSmrg
1063209ff23fSmrg    CAdjRCb = 0.0;
1064209ff23fSmrg    CAdjRCr = 1.59619140625;
1065209ff23fSmrg    CAdjGCb = -0.39111328125;
1066209ff23fSmrg    CAdjGCr = -0.8125;
1067209ff23fSmrg    CAdjBCb = 2.01708984375;
1068209ff23fSmrg    CAdjBCr = 0;
1069209ff23fSmrg#endif
1070209ff23fSmrg
1071209ff23fSmrg    OvLuma = CAdjLuma * gamma_curve_r100[gamma].OvGammaCont;
1072209ff23fSmrg    OvRCb = CAdjRCb * gamma_curve_r100[gamma].OvGammaCont;
1073209ff23fSmrg    OvRCr = CAdjRCr * gamma_curve_r100[gamma].OvGammaCont;
1074209ff23fSmrg    OvGCb = CAdjGCb * gamma_curve_r100[gamma].OvGammaCont;
1075209ff23fSmrg    OvGCr = CAdjGCr * gamma_curve_r100[gamma].OvGammaCont;
1076209ff23fSmrg    OvBCb = CAdjBCb * gamma_curve_r100[gamma].OvGammaCont;
1077209ff23fSmrg    OvBCr = CAdjBCr * gamma_curve_r100[gamma].OvGammaCont;
1078b7e1c893Smrg    OvROff = RedAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
1079209ff23fSmrg	OvLuma * Loff - (OvRCb + OvRCr) * Coff;
1080b7e1c893Smrg    OvGOff = GreenAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
1081209ff23fSmrg	OvLuma * Loff - (OvGCb + OvGCr) * Coff;
1082b7e1c893Smrg    OvBOff = BlueAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont -
1083209ff23fSmrg	OvLuma * Loff - (OvBCb + OvBCr) * Coff;
1084209ff23fSmrg#if 0 /* default constants */
1085209ff23fSmrg    OvROff = -888.5;
1086209ff23fSmrg    OvGOff = 545;
1087209ff23fSmrg    OvBOff = -1104;
1088209ff23fSmrg#endif
1089209ff23fSmrg
1090209ff23fSmrg    OvROff = ClipValue(OvROff, -2048.0, 2047.5);
1091209ff23fSmrg    OvGOff = ClipValue(OvGOff, -2048.0, 2047.5);
1092209ff23fSmrg    OvBOff = ClipValue(OvBOff, -2048.0, 2047.5);
1093209ff23fSmrg    dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff;
1094209ff23fSmrg    dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff;
1095209ff23fSmrg    dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff;
1096209ff23fSmrg
1097209ff23fSmrg    if(info->ChipFamily == CHIP_FAMILY_RADEON)
1098209ff23fSmrg    {
1099209ff23fSmrg	dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17;
1100209ff23fSmrg	dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1;
1101209ff23fSmrg	dwOvRCr = (((INT32)(OvRCr * 2048.0))&0x7fff)<<17;
1102209ff23fSmrg	dwOvGCb = (((INT32)(OvGCb * 2048.0))&0x7fff)<<1;
1103209ff23fSmrg	dwOvGCr = (((INT32)(OvGCr * 2048.0))&0x7fff)<<17;
1104209ff23fSmrg	dwOvBCb = (((INT32)(OvBCb * 2048.0))&0x7fff)<<1;
1105209ff23fSmrg	dwOvBCr = (((INT32)(OvBCr * 2048.0))&0x7fff)<<17;
1106209ff23fSmrg    }
1107209ff23fSmrg    else
1108209ff23fSmrg    {
1109209ff23fSmrg	dwOvLuma = (((INT32)(OvLuma * 256.0))&0xfff)<<20;
1110209ff23fSmrg	dwOvRCb = (((INT32)(OvRCb * 256.0))&0xfff)<<4;
1111209ff23fSmrg	dwOvRCr = (((INT32)(OvRCr * 256.0))&0xfff)<<20;
1112209ff23fSmrg	dwOvGCb = (((INT32)(OvGCb * 256.0))&0xfff)<<4;
1113209ff23fSmrg	dwOvGCr = (((INT32)(OvGCr * 256.0))&0xfff)<<20;
1114209ff23fSmrg	dwOvBCb = (((INT32)(OvBCb * 256.0))&0xfff)<<4;
1115209ff23fSmrg	dwOvBCr = (((INT32)(OvBCr * 256.0))&0xfff)<<20;
1116209ff23fSmrg    }
1117209ff23fSmrg
1118209ff23fSmrg    /* set gamma */
1119209ff23fSmrg    RADEONSetOverlayGamma(pScrn, gamma);
1120209ff23fSmrg
1121209ff23fSmrg    /* color transforms */
1122209ff23fSmrg    OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma);
1123209ff23fSmrg    OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr);
1124209ff23fSmrg    OUTREG(RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma);
1125209ff23fSmrg    OUTREG(RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr);
1126209ff23fSmrg    OUTREG(RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma);
1127209ff23fSmrg    OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr);
1128209ff23fSmrg}
1129209ff23fSmrg
1130209ff23fSmrgstatic void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode)
1131209ff23fSmrg{
1132209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1133209ff23fSmrg    unsigned char *RADEONMMIO = info->MMIO;
1134209ff23fSmrg
1135209ff23fSmrg    if (alpha_mode == 0) { /* key mode */
1136209ff23fSmrg    	OUTREG(RADEON_OV0_KEY_CNTL,
1137209ff23fSmrg		RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */
1138209ff23fSmrg		RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */
1139209ff23fSmrg		RADEON_CMP_MIX_OR);
1140209ff23fSmrg    	/* crtc 1 */
1141209ff23fSmrg    	OUTREG(RADEON_DISP_MERGE_CNTL,
1142209ff23fSmrg		(RADEON_DISP_ALPHA_MODE_KEY &
1143209ff23fSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
1144209ff23fSmrg		((gr_alpha << 0x00000010) &
1145209ff23fSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
1146209ff23fSmrg		((ov_alpha << 0x00000018) &
1147209ff23fSmrg		RADEON_DISP_OV0_ALPHA_MASK));
1148209ff23fSmrg    	/* crtc 2 */
1149209ff23fSmrg    	OUTREG(RADEON_DISP2_MERGE_CNTL,
1150209ff23fSmrg		(RADEON_DISP_ALPHA_MODE_KEY &
1151209ff23fSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
1152209ff23fSmrg		((gr_alpha << 0x00000010) &
1153209ff23fSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
1154209ff23fSmrg		((ov_alpha << 0x00000018) &
1155209ff23fSmrg		RADEON_DISP_OV0_ALPHA_MASK));
1156209ff23fSmrg    } else { /* global mode */
1157209ff23fSmrg    	OUTREG(RADEON_OV0_KEY_CNTL,
1158209ff23fSmrg		RADEON_GRAPHIC_KEY_FN_FALSE |   /* what does this do? */
1159209ff23fSmrg		RADEON_VIDEO_KEY_FN_FALSE |   /* what does this do? */
1160209ff23fSmrg		RADEON_CMP_MIX_AND);
1161209ff23fSmrg    	/* crtc 2 */
1162209ff23fSmrg    	OUTREG(RADEON_DISP2_MERGE_CNTL,
1163209ff23fSmrg		(RADEON_DISP_ALPHA_MODE_GLOBAL &
1164209ff23fSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
1165209ff23fSmrg		((gr_alpha << 0x00000010) &
1166209ff23fSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
1167209ff23fSmrg		((ov_alpha << 0x00000018) &
1168209ff23fSmrg		RADEON_DISP_OV0_ALPHA_MASK));
1169209ff23fSmrg    	/* crtc 1 */
1170209ff23fSmrg    	OUTREG(RADEON_DISP_MERGE_CNTL,
1171209ff23fSmrg		(RADEON_DISP_ALPHA_MODE_GLOBAL &
1172209ff23fSmrg		RADEON_DISP_ALPHA_MODE_MASK) |
1173209ff23fSmrg		((gr_alpha << 0x00000010) &
1174209ff23fSmrg		RADEON_DISP_GRPH_ALPHA_MASK) |
1175209ff23fSmrg		((ov_alpha << 0x00000018) &
1176209ff23fSmrg		RADEON_DISP_OV0_ALPHA_MASK));
1177209ff23fSmrg    }
1178209ff23fSmrg     /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */
1179209ff23fSmrg     /* not yet supported */
1180209ff23fSmrg}
1181209ff23fSmrg
1182209ff23fSmrgstatic void RADEONSetColorKey(ScrnInfoPtr pScrn, uint32_t colorKey)
1183209ff23fSmrg{
1184209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1185209ff23fSmrg    unsigned char *RADEONMMIO = info->MMIO;
1186209ff23fSmrg    uint32_t min, max;
1187209ff23fSmrg    uint8_t r, g, b;
1188209ff23fSmrg
1189209ff23fSmrg    if (info->CurrentLayout.depth > 8)
1190209ff23fSmrg    {
1191209ff23fSmrg	uint32_t	rbits, gbits, bbits;
1192209ff23fSmrg
1193209ff23fSmrg	rbits = (colorKey & pScrn->mask.red) >> pScrn->offset.red;
1194209ff23fSmrg	gbits = (colorKey & pScrn->mask.green) >> pScrn->offset.green;
1195209ff23fSmrg	bbits = (colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
1196209ff23fSmrg
1197209ff23fSmrg	r = rbits << (8 - pScrn->weight.red);
1198209ff23fSmrg	g = gbits << (8 - pScrn->weight.green);
1199209ff23fSmrg	b = bbits << (8 - pScrn->weight.blue);
1200209ff23fSmrg    }
1201209ff23fSmrg    else
1202209ff23fSmrg    {
1203209ff23fSmrg	uint32_t	bits;
1204209ff23fSmrg
1205209ff23fSmrg	bits = colorKey & ((1 << info->CurrentLayout.depth) - 1);
1206209ff23fSmrg	r = bits;
1207209ff23fSmrg	g = bits;
1208209ff23fSmrg	b = bits;
1209209ff23fSmrg    }
1210209ff23fSmrg    min = (r << 16) | (g << 8) | (b);
1211209ff23fSmrg    max = (0xff << 24) | (r << 16) | (g << 8) | (b);
1212209ff23fSmrg
1213209ff23fSmrg    RADEONWaitForFifo(pScrn, 2);
1214209ff23fSmrg    OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max);
1215209ff23fSmrg    OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min);
1216209ff23fSmrg}
1217209ff23fSmrg
1218209ff23fSmrgvoid
1219209ff23fSmrgRADEONResetVideo(ScrnInfoPtr pScrn)
1220209ff23fSmrg{
1221209ff23fSmrg    RADEONInfoPtr   info      = RADEONPTR(pScrn);
1222209ff23fSmrg    unsigned char *RADEONMMIO = info->MMIO;
1223209ff23fSmrg    RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
1224209ff23fSmrg    char tmp[200];
1225209ff23fSmrg
1226209ff23fSmrg    /* this function is called from ScreenInit. pScreen is used
1227209ff23fSmrg       by XAA internally, but not valid until ScreenInit finishs.
1228209ff23fSmrg    */
1229209ff23fSmrg    if (info->accelOn && pScrn->pScreen)
1230209ff23fSmrg	RADEON_SYNC(info, pScrn);
1231209ff23fSmrg
1232209ff23fSmrg    /* this is done here because each time the server is reset these
1233209ff23fSmrg       could change.. Otherwise they remain constant */
1234209ff23fSmrg    xvInstanceID = MAKE_ATOM("XV_INSTANCE_ID");
1235209ff23fSmrg    xvDeviceID = MAKE_ATOM("XV_DEVICE_ID");
1236209ff23fSmrg    xvLocationID = MAKE_ATOM("XV_LOCATION_ID");
1237209ff23fSmrg    xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS");
1238209ff23fSmrg
1239209ff23fSmrg    xvBrightness   = MAKE_ATOM("XV_BRIGHTNESS");
1240209ff23fSmrg    xvSaturation   = MAKE_ATOM("XV_SATURATION");
1241209ff23fSmrg    xvColor        = MAKE_ATOM("XV_COLOR");
1242209ff23fSmrg    xvContrast     = MAKE_ATOM("XV_CONTRAST");
1243209ff23fSmrg    xvColorKey     = MAKE_ATOM("XV_COLORKEY");
1244209ff23fSmrg    xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
1245209ff23fSmrg    xvHue          = MAKE_ATOM("XV_HUE");
1246209ff23fSmrg    xvRedIntensity   = MAKE_ATOM("XV_RED_INTENSITY");
1247209ff23fSmrg    xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY");
1248209ff23fSmrg    xvBlueIntensity  = MAKE_ATOM("XV_BLUE_INTENSITY");
1249209ff23fSmrg    xvGamma          = MAKE_ATOM("XV_GAMMA");
1250209ff23fSmrg    xvColorspace     = MAKE_ATOM("XV_COLORSPACE");
1251209ff23fSmrg
1252209ff23fSmrg    xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
1253209ff23fSmrg    xvSetDefaults       = MAKE_ATOM("XV_SET_DEFAULTS");
1254209ff23fSmrg    xvCRTC              = MAKE_ATOM("XV_CRTC");
1255209ff23fSmrg
1256209ff23fSmrg    xvOvAlpha	      = MAKE_ATOM("XV_OVERLAY_ALPHA");
1257209ff23fSmrg    xvGrAlpha	      = MAKE_ATOM("XV_GRAPHICS_ALPHA");
1258209ff23fSmrg    xvAlphaMode       = MAKE_ATOM("XV_ALPHA_MODE");
1259209ff23fSmrg
1260209ff23fSmrg    xvOverlayDeinterlacingMethod = MAKE_ATOM("XV_OVERLAY_DEINTERLACING_METHOD");
1261209ff23fSmrg
1262209ff23fSmrg    xvDecBrightness   = MAKE_ATOM("XV_DEC_BRIGHTNESS");
1263209ff23fSmrg    xvDecSaturation   = MAKE_ATOM("XV_DEC_SATURATION");
1264209ff23fSmrg    xvDecColor        = MAKE_ATOM("XV_DEC_COLOR");
1265209ff23fSmrg    xvDecContrast     = MAKE_ATOM("XV_DEC_CONTRAST");
1266209ff23fSmrg    xvDecHue          = MAKE_ATOM("XV_DEC_HUE");
1267209ff23fSmrg
1268209ff23fSmrg    xvEncoding        = MAKE_ATOM("XV_ENCODING");
1269209ff23fSmrg    xvFrequency       = MAKE_ATOM("XV_FREQ");
1270209ff23fSmrg    xvTunerStatus     = MAKE_ATOM("XV_TUNER_STATUS");
1271209ff23fSmrg    xvVolume          = MAKE_ATOM("XV_VOLUME");
1272209ff23fSmrg    xvMute            = MAKE_ATOM("XV_MUTE");
1273209ff23fSmrg    xvSAP             = MAKE_ATOM("XV_SAP");
1274209ff23fSmrg
1275209ff23fSmrg    xvAdjustment      = MAKE_ATOM("XV_DEBUG_ADJUSTMENT");
1276209ff23fSmrg
1277209ff23fSmrg    sprintf(tmp, "RXXX:%d.%d.%d", PCI_DEV_VENDOR_ID(info->PciInfo),
1278209ff23fSmrg	    PCI_DEV_DEVICE_ID(info->PciInfo), PCI_DEV_REVISION(info->PciInfo));
1279209ff23fSmrg    pPriv->device_id = MAKE_ATOM(tmp);
1280209ff23fSmrg    sprintf(tmp, "PCI:%02d:%02d.%d", PCI_DEV_BUS(info->PciInfo),
1281209ff23fSmrg	    PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo));
1282209ff23fSmrg    pPriv->location_id = MAKE_ATOM(tmp);
1283209ff23fSmrg    sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex);
1284209ff23fSmrg    pPriv->instance_id = MAKE_ATOM(tmp);
1285209ff23fSmrg
1286209ff23fSmrg    OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOFT_RESET);
1287209ff23fSmrg    OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0);   /* maybe */
1288209ff23fSmrg    OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0);
1289209ff23fSmrg    OUTREG(RADEON_OV0_FILTER_CNTL, RADEON_FILTER_PROGRAMMABLE_COEF);
1290209ff23fSmrg    OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ |
1291209ff23fSmrg				RADEON_VIDEO_KEY_FN_FALSE |
1292209ff23fSmrg				RADEON_CMP_MIX_OR);
1293209ff23fSmrg    OUTREG(RADEON_OV0_TEST, 0);
1294209ff23fSmrg    OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
1295209ff23fSmrg    OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
1296209ff23fSmrg    RADEONSetColorKey(pScrn, pPriv->colorKey);
1297209ff23fSmrg
1298209ff23fSmrg    if (info->ChipFamily == CHIP_FAMILY_RADEON) {
1299209ff23fSmrg
1300209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000);
1301209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e);
1302209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0);
1303209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442);
1304209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040);
1305209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
1306209ff23fSmrg
1307209ff23fSmrg    } else {
1308209ff23fSmrg
1309209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000);
1310209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e);
1311209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da);
1312209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442);
1313209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046);
1314209ff23fSmrg	OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
1315209ff23fSmrg    }
1316209ff23fSmrg	/*
1317209ff23fSmrg	 * Set default Gamma ramp:
1318209ff23fSmrg	 *
1319209ff23fSmrg	 * Of 18 segments for gamma curve, all segments in R200 (and
1320209ff23fSmrg	 * newer) are programmable, while only lower 4 and upper 2
1321209ff23fSmrg	 * segments are programmable in the older Radeons.
1322209ff23fSmrg	 */
1323209ff23fSmrg
1324209ff23fSmrg    RADEONSetOverlayGamma(pScrn, 0); /* gamma = 1.0 */
1325209ff23fSmrg
1326209ff23fSmrg    if(pPriv->VIP!=NULL){
1327209ff23fSmrg        RADEONVIP_reset(pScrn,pPriv);
1328209ff23fSmrg        }
1329209ff23fSmrg
1330209ff23fSmrg    if(pPriv->theatre != NULL) {
1331209ff23fSmrg        xf86_InitTheatre(pPriv->theatre);
1332209ff23fSmrg/*      xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); */
1333209ff23fSmrg        }
1334209ff23fSmrg
1335209ff23fSmrg    if(pPriv->i2c != NULL){
1336209ff23fSmrg        RADEONResetI2C(pScrn, pPriv);
1337209ff23fSmrg        }
1338209ff23fSmrg}
1339209ff23fSmrg
1340209ff23fSmrgstatic void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
1341209ff23fSmrg{
1342209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1343209ff23fSmrg    RADEONPLLPtr  pll = &(info->pll);
1344209ff23fSmrg    TheatrePtr t;
1345209ff23fSmrg
1346209ff23fSmrg    uint8_t a;
1347209ff23fSmrg    int i;
1348209ff23fSmrg
1349209ff23fSmrg    pPriv->theatre = NULL;
1350209ff23fSmrg
1351209ff23fSmrg    if(!info->MM_TABLE_valid &&
1352209ff23fSmrg       !((info->RageTheatreCrystal>=0) &&
1353209ff23fSmrg           (info->RageTheatreTunerPort>=0) && (info->RageTheatreCompositePort>=0) &&
1354209ff23fSmrg           (info->RageTheatreSVideoPort>=0)))
1355209ff23fSmrg    {
1356209ff23fSmrg       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no multimedia table present, disabling Rage Theatre.\n");
1357209ff23fSmrg       return;
1358209ff23fSmrg    }
1359209ff23fSmrg
1360209ff23fSmrg    /* Go and find Rage Theatre, if it exists */
1361209ff23fSmrg
1362209ff23fSmrg    if (info->IsMobility)
1363209ff23fSmrg	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n");
1364209ff23fSmrg    else
1365209ff23fSmrg	pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
1366209ff23fSmrg
1367209ff23fSmrg    if(pPriv->theatre==NULL)return;
1368209ff23fSmrg
1369209ff23fSmrg    /* just a matter of convenience */
1370209ff23fSmrg    t=pPriv->theatre;
1371209ff23fSmrg
1372209ff23fSmrg    t->video_decoder_type=info->video_decoder_type;
1373209ff23fSmrg
1374209ff23fSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type is 0x%04x (BIOS value) versus 0x%04x (current PLL setting)\n",
1375209ff23fSmrg         t->video_decoder_type, pll->xclk);
1376209ff23fSmrg
1377209ff23fSmrg    if(info->MM_TABLE_valid){
1378209ff23fSmrg         for(i=0;i<5;i++){
1379209ff23fSmrg                a=info->MM_TABLE.input[i];
1380209ff23fSmrg
1381209ff23fSmrg                switch(a & 0x3){
1382209ff23fSmrg                        case 1:
1383209ff23fSmrg                                t->wTunerConnector=i;
1384209ff23fSmrg                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tuner is on port %d\n",i);
1385209ff23fSmrg                                break;
1386209ff23fSmrg                        case 2:  if(a & 0x4){
1387209ff23fSmrg                                   t->wComp0Connector=RT_COMP2;
1388209ff23fSmrg                                   } else {
1389209ff23fSmrg                                   t->wComp0Connector=RT_COMP1;
1390209ff23fSmrg                                   }
1391209ff23fSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector);
1392209ff23fSmrg                                  break;
1393209ff23fSmrg                        case 3:  if(a & 0x4){
1394209ff23fSmrg                                   t->wSVideo0Connector=RT_YCR_COMP4;
1395209ff23fSmrg                                   } else {
1396209ff23fSmrg                                   t->wSVideo0Connector=RT_YCF_COMP4;
1397209ff23fSmrg                                   }
1398209ff23fSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector);
1399209ff23fSmrg                                   break;
1400209ff23fSmrg                        default:
1401209ff23fSmrg                                break;
1402209ff23fSmrg                        }
1403209ff23fSmrg                }
1404209ff23fSmrg        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n",
1405209ff23fSmrg    	     (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
1406209ff23fSmrg
1407209ff23fSmrg         }
1408209ff23fSmrg
1409209ff23fSmrg    if(info->RageTheatreTunerPort>=0)t->wTunerConnector=info->RageTheatreTunerPort;
1410209ff23fSmrg    if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort;
1411209ff23fSmrg    if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort;
1412209ff23fSmrg
1413209ff23fSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n",
1414209ff23fSmrg    	(unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
1415209ff23fSmrg
1416209ff23fSmrg    switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){
1417209ff23fSmrg                case 2700:
1418209ff23fSmrg                        t->video_decoder_type=RT_FREF_2700;
1419209ff23fSmrg                        break;
1420209ff23fSmrg                case 2950:
1421209ff23fSmrg                        t->video_decoder_type=RT_FREF_2950;
1422209ff23fSmrg                        break;
1423209ff23fSmrg                default:
1424209ff23fSmrg                        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1425209ff23fSmrg                                "Unsupported reference clock frequency, Rage Theatre disabled\n");
1426209ff23fSmrg                        t->theatre_num=-1;
14272f39173dSmrg			free(pPriv->theatre);
1428209ff23fSmrg			pPriv->theatre = NULL;
1429209ff23fSmrg			return;
1430209ff23fSmrg                }
1431209ff23fSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type used: 0x%04x\n", t->video_decoder_type);
1432209ff23fSmrg}
1433209ff23fSmrg
1434209ff23fSmrgstatic XF86VideoAdaptorPtr
1435209ff23fSmrgRADEONAllocAdaptor(ScrnInfoPtr pScrn)
1436209ff23fSmrg{
1437209ff23fSmrg    XF86VideoAdaptorPtr adapt;
1438209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1439209ff23fSmrg    RADEONPortPrivPtr pPriv;
1440209ff23fSmrg    uint32_t dot_clock;
1441209ff23fSmrg    int ecp;
1442209ff23fSmrg
1443209ff23fSmrg    if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
1444209ff23fSmrg	return NULL;
1445209ff23fSmrg
14462f39173dSmrg    if(!(pPriv = calloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion))))
1447209ff23fSmrg    {
14482f39173dSmrg	free(adapt);
1449209ff23fSmrg	return NULL;
1450209ff23fSmrg    }
1451209ff23fSmrg
1452209ff23fSmrg    adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
1453209ff23fSmrg    adapt->pPortPrivates[0].ptr = (pointer)pPriv;
1454209ff23fSmrg
1455209ff23fSmrg    pPriv->colorKey = info->videoKey;
1456209ff23fSmrg    pPriv->doubleBuffer = TRUE;
1457209ff23fSmrg    pPriv->videoStatus = 0;
1458209ff23fSmrg    pPriv->brightness = 0;
1459209ff23fSmrg    pPriv->transform_index = 0;
1460209ff23fSmrg    pPriv->saturation = 0;
1461209ff23fSmrg    pPriv->contrast = 0;
1462209ff23fSmrg    pPriv->red_intensity = 0;
1463209ff23fSmrg    pPriv->green_intensity = 0;
1464209ff23fSmrg    pPriv->blue_intensity = 0;
1465209ff23fSmrg    pPriv->hue = 0;
1466209ff23fSmrg    pPriv->currentBuffer = 0;
1467209ff23fSmrg    pPriv->autopaint_colorkey = TRUE;
1468209ff23fSmrg    pPriv->gamma = 1000;
1469209ff23fSmrg    pPriv->desired_crtc = NULL;
1470209ff23fSmrg
1471209ff23fSmrg    pPriv->ov_alpha = 255;
1472209ff23fSmrg    pPriv->gr_alpha = 255;
1473209ff23fSmrg    pPriv->alpha_mode = 0;
1474209ff23fSmrg
1475209ff23fSmrg       /* TV-in stuff */
1476209ff23fSmrg    pPriv->video_stream_active = FALSE;
1477209ff23fSmrg    pPriv->encoding = 4;
1478209ff23fSmrg    pPriv->frequency = 1000;
1479209ff23fSmrg    pPriv->volume = -1000;
1480209ff23fSmrg    pPriv->mute = TRUE;
1481209ff23fSmrg    pPriv->v = 0;
1482209ff23fSmrg    pPriv->overlay_deinterlacing_method = METHOD_BOB;
1483209ff23fSmrg    pPriv->capture_vbi_data = 0;
1484209ff23fSmrg    pPriv->dec_brightness = 0;
1485209ff23fSmrg    pPriv->dec_saturation = 0;
1486209ff23fSmrg    pPriv->dec_contrast = 0;
1487209ff23fSmrg    pPriv->dec_hue = 0;
1488209ff23fSmrg
1489209ff23fSmrg
1490209ff23fSmrg    /*
1491209ff23fSmrg     * Unlike older Mach64 chips, RADEON has only two ECP settings:
1492209ff23fSmrg     * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
1493209ff23fSmrg     * for higher clocks, sure makes life nicer
1494209ff23fSmrg     */
1495209ff23fSmrg    dot_clock = info->ModeReg->dot_clock_freq;
1496209ff23fSmrg
1497209ff23fSmrg    if (dot_clock < 17500)
1498209ff23fSmrg        info->ecp_div = 0;
1499209ff23fSmrg    else
1500209ff23fSmrg        info->ecp_div = 1;
1501209ff23fSmrg    ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
1502209ff23fSmrg
1503209ff23fSmrg    if (info->IsIGP) {
1504209ff23fSmrg        /* Force the overlay clock on for integrated chips
1505209ff23fSmrg	 */
1506209ff23fSmrg        ecp |= (1<<18);
1507209ff23fSmrg    }
1508209ff23fSmrg
1509209ff23fSmrg    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp);
1510209ff23fSmrg
1511209ff23fSmrg
1512209ff23fSmrg    /* Decide on tuner type */
1513209ff23fSmrg    if((info->tunerType<0) && (info->MM_TABLE_valid)) {
1514209ff23fSmrg        pPriv->tuner_type = info->MM_TABLE.tuner_type;
1515209ff23fSmrg    	} else
1516209ff23fSmrg        pPriv->tuner_type = info->tunerType;
1517209ff23fSmrg
1518209ff23fSmrg    /* Initialize I2C bus */
1519209ff23fSmrg    RADEONInitI2C(pScrn, pPriv);
1520209ff23fSmrg    if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
1521209ff23fSmrg
1522209ff23fSmrg
1523209ff23fSmrg    #if 0  /* this is just here for easy debugging - normally off */
1524209ff23fSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n");
1525209ff23fSmrg    for(i=0;i<255;i+=2)
1526209ff23fSmrg        if(RADEONProbeAddress(pPriv->i2c, i))
1527209ff23fSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "     found device at address 0x%02x\n", i);
1528209ff23fSmrg    #endif
1529209ff23fSmrg
1530209ff23fSmrg    /* resetting the VIP bus causes problems with some mobility chips.
1531209ff23fSmrg     * we don't support video in on any mobility chips at the moment anyway
1532209ff23fSmrg     */
1533209ff23fSmrg    /* Initialize VIP bus */
1534209ff23fSmrg    if (!info->IsMobility)
1535209ff23fSmrg	RADEONVIP_init(pScrn, pPriv);
1536209ff23fSmrg
1537209ff23fSmrg    info->adaptor = adapt;
1538921a55d8Smrg    info->xv_max_width = 2047;
1539921a55d8Smrg    info->xv_max_height = 2047;
1540209ff23fSmrg
1541209ff23fSmrg	if(!xf86LoadSubModule(pScrn,"theatre_detect"))
1542209ff23fSmrg	{
1543209ff23fSmrg		xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n");
1544209ff23fSmrg		goto skip_theatre;
1545209ff23fSmrg    }
1546209ff23fSmrg	RADEONSetupTheatre(pScrn, pPriv);
1547209ff23fSmrg
1548209ff23fSmrg	/*
1549209ff23fSmrg	 * Now load the correspondind theatre chip based on what has been detected.
1550209ff23fSmrg	 */
1551209ff23fSmrg	if (pPriv->theatre)
1552209ff23fSmrg	{
1553209ff23fSmrg		xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Going to load the corresponding theatre module\n");
1554209ff23fSmrg		switch (pPriv->theatre->theatre_id)
1555209ff23fSmrg		{
1556209ff23fSmrg			case RT100_ATI_ID:
1557209ff23fSmrg			{
1558209ff23fSmrg				if(!xf86LoadSubModule(pScrn,"theatre"))
1559209ff23fSmrg				{
1560209ff23fSmrg					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
15612f39173dSmrg					free(pPriv->theatre);
1562209ff23fSmrg					goto skip_theatre;
1563209ff23fSmrg				}
1564209ff23fSmrg				break;
1565209ff23fSmrg			}
1566209ff23fSmrg			case RT200_ATI_ID:
1567209ff23fSmrg			{
1568209ff23fSmrg				if(!xf86LoadSubModule(pScrn,"theatre200"))
1569209ff23fSmrg				{
1570209ff23fSmrg					xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n");
15712f39173dSmrg					free(pPriv->theatre);
1572209ff23fSmrg					goto skip_theatre;
1573209ff23fSmrg				}
1574209ff23fSmrg				pPriv->theatre->microc_path = info->RageTheatreMicrocPath;
1575209ff23fSmrg				pPriv->theatre->microc_type = info->RageTheatreMicrocType;
1576209ff23fSmrg				break;
1577209ff23fSmrg			}
1578209ff23fSmrg			default:
1579209ff23fSmrg			{
1580209ff23fSmrg				xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unknown Theatre chip\n");
15812f39173dSmrg				free(pPriv->theatre);
1582209ff23fSmrg				goto skip_theatre;
1583209ff23fSmrg			}
1584209ff23fSmrg		}
1585209ff23fSmrg	}
1586209ff23fSmrg
1587209ff23fSmrg	if(pPriv->theatre!=NULL)
1588209ff23fSmrg	{
1589209ff23fSmrg		xf86_InitTheatre(pPriv->theatre);
1590209ff23fSmrg		if(pPriv->theatre->mode == MODE_UNINITIALIZED)
1591209ff23fSmrg		{
15922f39173dSmrg			free(pPriv->theatre);
1593209ff23fSmrg			pPriv->theatre = NULL;
1594209ff23fSmrg			xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Rage Theatre disabled\n");
1595209ff23fSmrg			/* Here the modules must be unloaded */
1596209ff23fSmrg			goto skip_theatre;
1597209ff23fSmrg		}
1598209ff23fSmrg	}
1599209ff23fSmrg
1600209ff23fSmrg    if(pPriv->theatre!=NULL){
1601209ff23fSmrg        xf86_ResetTheatreRegsForNoTVout(pPriv->theatre);
1602209ff23fSmrg        xf86_RT_SetTint(pPriv->theatre, pPriv->dec_hue);
1603209ff23fSmrg        xf86_RT_SetSaturation(pPriv->theatre, pPriv->dec_saturation);
1604209ff23fSmrg        xf86_RT_SetSharpness(pPriv->theatre, RT_NORM_SHARPNESS);
1605209ff23fSmrg        xf86_RT_SetContrast(pPriv->theatre, pPriv->dec_contrast);
1606209ff23fSmrg        xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
1607209ff23fSmrg
1608209ff23fSmrg        RADEON_RT_SetEncoding(pScrn, pPriv);
1609209ff23fSmrg	}
1610209ff23fSmrg
1611209ff23fSmrgskip_theatre:
1612209ff23fSmrg
1613209ff23fSmrg    return adapt;
1614209ff23fSmrg}
1615209ff23fSmrg
1616209ff23fSmrgstatic XF86VideoAdaptorPtr
1617209ff23fSmrgRADEONSetupImageVideo(ScreenPtr pScreen)
1618209ff23fSmrg{
1619209ff23fSmrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1620209ff23fSmrg    RADEONPortPrivPtr pPriv;
1621209ff23fSmrg    XF86VideoAdaptorPtr adapt;
1622209ff23fSmrg
1623209ff23fSmrg    if(!(adapt = RADEONAllocAdaptor(pScrn)))
1624209ff23fSmrg	return NULL;
1625209ff23fSmrg
1626209ff23fSmrg    adapt->type = XvWindowMask | XvInputMask | XvImageMask;
1627209ff23fSmrg    adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
1628209ff23fSmrg    adapt->name = "ATI Radeon Video Overlay";
1629209ff23fSmrg    adapt->nEncodings = 1;
1630209ff23fSmrg    adapt->pEncodings = &DummyEncoding;
1631209ff23fSmrg    adapt->nFormats = NUM_FORMATS;
1632209ff23fSmrg    adapt->pFormats = Formats;
1633209ff23fSmrg    adapt->nPorts = 1;
1634209ff23fSmrg    adapt->nAttributes = NUM_ATTRIBUTES;
1635209ff23fSmrg    adapt->pAttributes = Attributes;
1636209ff23fSmrg    adapt->nImages = NUM_IMAGES;
1637209ff23fSmrg    adapt->pImages = Images;
1638209ff23fSmrg    adapt->PutVideo = NULL;
1639209ff23fSmrg    adapt->PutStill = NULL;
1640209ff23fSmrg    adapt->GetVideo = NULL;
1641209ff23fSmrg    adapt->GetStill = NULL;
1642209ff23fSmrg    adapt->StopVideo = RADEONStopVideo;
1643209ff23fSmrg    adapt->SetPortAttribute = RADEONSetPortAttribute;
1644209ff23fSmrg    adapt->GetPortAttribute = RADEONGetPortAttribute;
1645209ff23fSmrg    adapt->QueryBestSize = RADEONQueryBestSize;
1646209ff23fSmrg    adapt->PutImage = RADEONPutImage;
1647209ff23fSmrg    adapt->QueryImageAttributes = RADEONQueryImageAttributes;
1648209ff23fSmrg
1649209ff23fSmrg    pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr);
1650209ff23fSmrg    REGION_NULL(pScreen, &(pPriv->clip));
1651209ff23fSmrg
1652209ff23fSmrg    pPriv->textured = FALSE;
1653209ff23fSmrg
1654b7e1c893Smrg    if(pPriv->theatre != NULL) {
1655209ff23fSmrg	/* video decoder is present, extend capabilities */
1656209ff23fSmrg       adapt->nEncodings = 13;
1657209ff23fSmrg       adapt->pEncodings = InputVideoEncodings;
1658209ff23fSmrg       adapt->type |= XvVideoMask;
1659b7e1c893Smrg       adapt->nAttributes = NUM_DEC_ATTRIBUTES;
1660209ff23fSmrg       adapt->PutVideo = RADEONPutVideo;
1661209ff23fSmrg    }
1662209ff23fSmrg
1663209ff23fSmrg    RADEONResetVideo(pScrn);
1664209ff23fSmrg
1665209ff23fSmrg    return adapt;
1666209ff23fSmrg}
1667209ff23fSmrg
1668921a55d8Smrgvoid
1669921a55d8SmrgRADEONFreeVideoMemory(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
1670921a55d8Smrg{
1671921a55d8Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1672921a55d8Smrg
1673921a55d8Smrg    if (pPriv->video_memory != NULL) {
1674921a55d8Smrg	radeon_legacy_free_memory(pScrn, pPriv->video_memory);
1675921a55d8Smrg	pPriv->video_memory = NULL;
1676921a55d8Smrg
1677921a55d8Smrg	if (info->cs && pPriv->textured) {
1678921a55d8Smrg	    pPriv->src_bo[0] = NULL;
1679921a55d8Smrg	    radeon_legacy_free_memory(pScrn, pPriv->src_bo[1]);
1680921a55d8Smrg	    pPriv->src_bo[1] = NULL;
1681921a55d8Smrg	}
1682921a55d8Smrg    }
1683921a55d8Smrg}
1684921a55d8Smrg
1685209ff23fSmrgvoid
1686209ff23fSmrgRADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
1687209ff23fSmrg{
1688209ff23fSmrg  RADEONInfoPtr info = RADEONPTR(pScrn);
1689209ff23fSmrg  unsigned char *RADEONMMIO = info->MMIO;
1690209ff23fSmrg  RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
1691209ff23fSmrg
1692b7e1c893Smrg  if (pPriv->textured) {
1693b7e1c893Smrg      if (cleanup) {
1694921a55d8Smrg	  RADEONFreeVideoMemory(pScrn, pPriv);
1695b7e1c893Smrg      }
1696b7e1c893Smrg      return;
1697b7e1c893Smrg  }
1698209ff23fSmrg
1699209ff23fSmrg  REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
1700209ff23fSmrg
1701209ff23fSmrg  if(cleanup) {
1702209ff23fSmrg     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
1703209ff23fSmrg	RADEONWaitForFifo(pScrn, 2);
1704209ff23fSmrg	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
1705209ff23fSmrg     }
1706209ff23fSmrg     if(pPriv->video_stream_active){
1707209ff23fSmrg        RADEONWaitForFifo(pScrn, 2);
1708209ff23fSmrg        OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
1709209ff23fSmrg        OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
1710209ff23fSmrg        RADEONResetVideo(pScrn);
1711209ff23fSmrg        pPriv->video_stream_active = FALSE;
1712209ff23fSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
1713209ff23fSmrg		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE);
1714209ff23fSmrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
1715209ff23fSmrg     }
1716921a55d8Smrg     RADEONFreeVideoMemory(pScrn, pPriv);
1717209ff23fSmrg     pPriv->videoStatus = 0;
1718209ff23fSmrg  } else {
1719209ff23fSmrg     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
1720209ff23fSmrg	pPriv->videoStatus |= OFF_TIMER;
1721209ff23fSmrg	pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
1722209ff23fSmrg     }
1723209ff23fSmrg  }
1724209ff23fSmrg}
1725209ff23fSmrg
1726209ff23fSmrgint
1727209ff23fSmrgRADEONSetPortAttribute(ScrnInfoPtr  pScrn,
1728209ff23fSmrg		       Atom	    attribute,
1729209ff23fSmrg		       INT32	    value,
1730209ff23fSmrg		       pointer	    data)
1731209ff23fSmrg{
1732209ff23fSmrg    RADEONInfoPtr	info = RADEONPTR(pScrn);
1733209ff23fSmrg    RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
1734209ff23fSmrg    Bool		setTransform = FALSE;
1735209ff23fSmrg    Bool		setAlpha = FALSE;
1736209ff23fSmrg    unsigned char *RADEONMMIO = info->MMIO;
1737209ff23fSmrg
1738209ff23fSmrg    RADEON_SYNC(info, pScrn);
1739209ff23fSmrg
1740209ff23fSmrg    if(attribute == xvAutopaintColorkey)
1741209ff23fSmrg    {
1742209ff23fSmrg	pPriv->autopaint_colorkey = ClipValue (value, 0, 1);
1743209ff23fSmrg    }
1744209ff23fSmrg    else if(attribute == xvSetDefaults)
1745209ff23fSmrg    {
1746209ff23fSmrg	pPriv->autopaint_colorkey = TRUE;
1747209ff23fSmrg	pPriv->brightness = 0;
1748209ff23fSmrg	pPriv->saturation = 0;
1749209ff23fSmrg	pPriv->contrast = 0;
1750209ff23fSmrg	pPriv->hue = 0;
1751209ff23fSmrg	pPriv->red_intensity = 0;
1752209ff23fSmrg	pPriv->green_intensity = 0;
1753209ff23fSmrg	pPriv->blue_intensity = 0;
1754209ff23fSmrg	pPriv->gamma = 1000;
1755209ff23fSmrg	pPriv->transform_index = 0;
1756209ff23fSmrg	pPriv->doubleBuffer = FALSE;
1757209ff23fSmrg	pPriv->ov_alpha = 255;
1758209ff23fSmrg	pPriv->gr_alpha = 255;
1759209ff23fSmrg	pPriv->alpha_mode = 0;
1760209ff23fSmrg
1761209ff23fSmrg        /* It is simpler to call itself */
1762209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data);
1763209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data);
1764209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvDecContrast,   0, data);
1765209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvDecHue,   0, data);
1766209ff23fSmrg
1767209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvVolume,   -1000, data);
1768209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvMute,   1, data);
1769209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvSAP,   0, data);
1770209ff23fSmrg        RADEONSetPortAttribute(pScrn, xvDoubleBuffer,   1, data);
1771209ff23fSmrg
1772209ff23fSmrg	setTransform = TRUE;
1773209ff23fSmrg	setAlpha = TRUE;
1774209ff23fSmrg    }
1775209ff23fSmrg    else if(attribute == xvBrightness)
1776209ff23fSmrg    {
1777209ff23fSmrg	pPriv->brightness = ClipValue (value, -1000, 1000);
1778209ff23fSmrg	setTransform = TRUE;
1779209ff23fSmrg    }
1780209ff23fSmrg    else if((attribute == xvSaturation) || (attribute == xvColor))
1781209ff23fSmrg    {
1782209ff23fSmrg	pPriv->saturation = ClipValue (value, -1000, 1000);
1783209ff23fSmrg	setTransform = TRUE;
1784209ff23fSmrg    }
1785209ff23fSmrg    else if(attribute == xvContrast)
1786209ff23fSmrg    {
1787209ff23fSmrg	pPriv->contrast = ClipValue (value, -1000, 1000);
1788209ff23fSmrg	setTransform = TRUE;
1789209ff23fSmrg    }
1790209ff23fSmrg    else if(attribute == xvHue)
1791209ff23fSmrg    {
1792209ff23fSmrg	pPriv->hue = ClipValue (value, -1000, 1000);
1793209ff23fSmrg	setTransform = TRUE;
1794209ff23fSmrg    }
1795209ff23fSmrg    else if(attribute == xvRedIntensity)
1796209ff23fSmrg    {
1797209ff23fSmrg	pPriv->red_intensity = ClipValue (value, -1000, 1000);
1798209ff23fSmrg	setTransform = TRUE;
1799209ff23fSmrg    }
1800209ff23fSmrg    else if(attribute == xvGreenIntensity)
1801209ff23fSmrg    {
1802209ff23fSmrg	pPriv->green_intensity = ClipValue (value, -1000, 1000);
1803209ff23fSmrg	setTransform = TRUE;
1804209ff23fSmrg    }
1805209ff23fSmrg    else if(attribute == xvBlueIntensity)
1806209ff23fSmrg    {
1807209ff23fSmrg	pPriv->blue_intensity = ClipValue (value, -1000, 1000);
1808209ff23fSmrg	setTransform = TRUE;
1809209ff23fSmrg    }
1810209ff23fSmrg    else if(attribute == xvGamma)
1811209ff23fSmrg    {
1812209ff23fSmrg	pPriv->gamma = ClipValue (value, 100, 10000);
1813209ff23fSmrg	setTransform = TRUE;
1814209ff23fSmrg    }
1815209ff23fSmrg    else if(attribute == xvColorspace)
1816209ff23fSmrg    {
1817209ff23fSmrg	pPriv->transform_index = ClipValue (value, 0, 1);
1818209ff23fSmrg	setTransform = TRUE;
1819209ff23fSmrg    }
1820209ff23fSmrg    else if(attribute == xvDoubleBuffer)
1821209ff23fSmrg    {
1822209ff23fSmrg	pPriv->doubleBuffer = ClipValue (value, 0, 1);
1823209ff23fSmrg    }
1824209ff23fSmrg    else if(attribute == xvColorKey)
1825209ff23fSmrg    {
1826209ff23fSmrg	pPriv->colorKey = value;
1827209ff23fSmrg	RADEONSetColorKey (pScrn, pPriv->colorKey);
1828209ff23fSmrg	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
1829209ff23fSmrg    }
1830209ff23fSmrg    else if(attribute == xvCRTC)
1831209ff23fSmrg    {
1832209ff23fSmrg	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1833209ff23fSmrg	if ((value < -1) || (value > xf86_config->num_crtc))
1834209ff23fSmrg	    return BadValue;
1835209ff23fSmrg	if (value < 0)
1836209ff23fSmrg	    pPriv->desired_crtc = NULL;
1837209ff23fSmrg	else
1838209ff23fSmrg	    pPriv->desired_crtc = xf86_config->crtc[value];
1839209ff23fSmrg    }
1840209ff23fSmrg    else if(attribute == xvOvAlpha)
1841209ff23fSmrg    {
1842209ff23fSmrg	pPriv->ov_alpha = ClipValue (value, 0, 255);
1843209ff23fSmrg	setAlpha = TRUE;
1844209ff23fSmrg    }
1845209ff23fSmrg    else if(attribute == xvGrAlpha)
1846209ff23fSmrg    {
1847209ff23fSmrg	pPriv->gr_alpha = ClipValue (value, 0, 255);
1848209ff23fSmrg	setAlpha = TRUE;
1849209ff23fSmrg    }
1850209ff23fSmrg    else if(attribute == xvAlphaMode)
1851209ff23fSmrg    {
1852209ff23fSmrg	pPriv->alpha_mode = ClipValue (value, 0, 1);
1853209ff23fSmrg	setAlpha = TRUE;
1854209ff23fSmrg    }
1855209ff23fSmrg    else if(attribute == xvDecBrightness)
1856209ff23fSmrg    {
1857209ff23fSmrg        pPriv->dec_brightness = value;
1858209ff23fSmrg        if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
1859209ff23fSmrg    }
1860209ff23fSmrg    else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
1861209ff23fSmrg    {
1862209ff23fSmrg        if(value<-1000)value = -1000;
1863209ff23fSmrg        if(value>1000)value = 1000;
1864209ff23fSmrg        pPriv->dec_saturation = value;
1865209ff23fSmrg        if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value);
1866209ff23fSmrg    }
1867209ff23fSmrg    else if(attribute == xvDecContrast)
1868209ff23fSmrg    {
1869209ff23fSmrg        pPriv->dec_contrast = value;
1870209ff23fSmrg        if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value);
1871209ff23fSmrg    }
1872209ff23fSmrg    else if(attribute == xvDecHue)
1873209ff23fSmrg    {
1874209ff23fSmrg        pPriv->dec_hue = value;
1875209ff23fSmrg        if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value);
1876209ff23fSmrg    }
1877209ff23fSmrg    else if(attribute == xvEncoding)
1878209ff23fSmrg    {
1879209ff23fSmrg        pPriv->encoding = value;
1880209ff23fSmrg        if(pPriv->video_stream_active)
1881209ff23fSmrg        {
1882209ff23fSmrg           if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);
1883209ff23fSmrg           if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
1884209ff23fSmrg           if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
1885209ff23fSmrg	   if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
1886209ff23fSmrg           if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
1887209ff23fSmrg        /* put more here to actually change it */
1888209ff23fSmrg        }
1889209ff23fSmrg   }
1890209ff23fSmrg   else if(attribute == xvFrequency)
1891209ff23fSmrg   {
1892209ff23fSmrg        pPriv->frequency = value;
1893209ff23fSmrg        /* mute volume if it was not muted before */
1894209ff23fSmrg        if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
1895209ff23fSmrg		if((pPriv->uda1380!=NULL)&& !pPriv->mute)xf86_uda1380_mute(pPriv->uda1380, TRUE);
1896209ff23fSmrg        if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value);
1897209ff23fSmrg/*        if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);  */
1898209ff23fSmrg        if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck))
1899209ff23fSmrg                xf86_InitMSP3430(pPriv->msp3430);
1900209ff23fSmrg        if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume));
1901209ff23fSmrg		if((pPriv->uda1380 != NULL)&& !pPriv->mute) xf86_uda1380_setvolume(pPriv->uda1380, pPriv->volume);
1902209ff23fSmrg   }
1903209ff23fSmrg   else if(attribute == xvMute)
1904209ff23fSmrg   {
1905209ff23fSmrg        pPriv->mute = value;
1906209ff23fSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
1907209ff23fSmrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
1908209ff23fSmrg		if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, pPriv->mute);
1909209ff23fSmrg   }
1910209ff23fSmrg   else if(attribute == xvSAP)
1911209ff23fSmrg   {
1912209ff23fSmrg        pPriv->sap_channel = value;
1913209ff23fSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3);
1914209ff23fSmrg   }
1915209ff23fSmrg   else if(attribute == xvVolume)
1916209ff23fSmrg   {
1917209ff23fSmrg        if(value<-1000)value = -1000;
1918209ff23fSmrg        if(value>1000)value = 1000;
1919209ff23fSmrg        pPriv->volume = value;
1920209ff23fSmrg        pPriv->mute = FALSE;
1921209ff23fSmrg        if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value));
1922209ff23fSmrg        if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
1923209ff23fSmrg		if(pPriv->uda1380 != NULL) xf86_uda1380_setvolume(pPriv->uda1380, value);
1924209ff23fSmrg   }
1925209ff23fSmrg   else if(attribute == xvOverlayDeinterlacingMethod)
1926209ff23fSmrg   {
1927209ff23fSmrg        if(value<0)value = 0;
1928209ff23fSmrg        if(value>2)value = 2;
1929209ff23fSmrg        pPriv->overlay_deinterlacing_method = value;
1930209ff23fSmrg        switch(pPriv->overlay_deinterlacing_method){
1931209ff23fSmrg                case METHOD_BOB:
1932209ff23fSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
1933209ff23fSmrg                        break;
1934209ff23fSmrg                case METHOD_SINGLE:
1935209ff23fSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
1936209ff23fSmrg                        break;
1937209ff23fSmrg                case METHOD_WEAVE:
1938209ff23fSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0);
1939209ff23fSmrg                        break;
1940209ff23fSmrg                default:
1941209ff23fSmrg                        OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
1942209ff23fSmrg                }
1943209ff23fSmrg   }
1944209ff23fSmrg   else if(attribute == xvDumpStatus)
1945209ff23fSmrg   {
1946209ff23fSmrg  	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n",
1947209ff23fSmrg		pScrn->currentMode->Flags,
1948209ff23fSmrg		pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" ,
1949209ff23fSmrg		pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : ""
1950209ff23fSmrg		);
1951209ff23fSmrg	if(pPriv->tda9885 != NULL){
1952209ff23fSmrg		xf86_tda9885_getstatus(pPriv->tda9885);
1953209ff23fSmrg		xf86_tda9885_dumpstatus(pPriv->tda9885);
1954209ff23fSmrg		}
1955209ff23fSmrg	if(pPriv->fi1236!=NULL){
1956209ff23fSmrg		xf86_fi1236_dump_status(pPriv->fi1236);
1957209ff23fSmrg		}
1958b7e1c893Smrg   }
1959209ff23fSmrg   else if(attribute == xvAdjustment)
1960209ff23fSmrg   {
1961209ff23fSmrg  	pPriv->adjustment=value;
1962209ff23fSmrg        xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n",
1963209ff23fSmrg		   (unsigned)pPriv->adjustment);
1964209ff23fSmrg  	if(pPriv->tda9885!=0){
1965209ff23fSmrg		pPriv->tda9885->top_adjustment=value;
1966209ff23fSmrg		RADEON_TDA9885_SetEncoding(pPriv);
1967209ff23fSmrg		}
1968209ff23fSmrg   }
1969209ff23fSmrg   else
1970209ff23fSmrg	return BadMatch;
1971209ff23fSmrg
1972209ff23fSmrg    if (setTransform)
1973209ff23fSmrg    {
1974209ff23fSmrg	RADEONSetTransform(pScrn,
1975209ff23fSmrg			   RTFBrightness(pPriv->brightness),
1976209ff23fSmrg			   RTFContrast(pPriv->contrast),
1977209ff23fSmrg			   RTFSaturation(pPriv->saturation),
1978209ff23fSmrg			   RTFHue(pPriv->hue),
1979209ff23fSmrg			   RTFIntensity(pPriv->red_intensity),
1980209ff23fSmrg			   RTFIntensity(pPriv->green_intensity),
1981209ff23fSmrg			   RTFIntensity(pPriv->blue_intensity),
1982209ff23fSmrg			   pPriv->transform_index,
1983209ff23fSmrg			   pPriv->gamma);
1984209ff23fSmrg    }
1985209ff23fSmrg
1986209ff23fSmrg    if (setAlpha)
1987209ff23fSmrg    {
1988209ff23fSmrg	RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode);
1989209ff23fSmrg    }
1990209ff23fSmrg
1991209ff23fSmrg    return Success;
1992209ff23fSmrg}
1993209ff23fSmrg
1994209ff23fSmrgint
1995209ff23fSmrgRADEONGetPortAttribute(ScrnInfoPtr  pScrn,
1996209ff23fSmrg		       Atom	    attribute,
1997209ff23fSmrg		       INT32	    *value,
1998209ff23fSmrg		       pointer	    data)
1999209ff23fSmrg{
2000209ff23fSmrg    RADEONInfoPtr	info = RADEONPTR(pScrn);
2001209ff23fSmrg    RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
2002209ff23fSmrg
2003209ff23fSmrg    if (info->accelOn) RADEON_SYNC(info, pScrn);
2004209ff23fSmrg
2005209ff23fSmrg    if(attribute == xvAutopaintColorkey)
2006209ff23fSmrg	*value = pPriv->autopaint_colorkey;
2007209ff23fSmrg    else if(attribute == xvBrightness)
2008209ff23fSmrg	*value = pPriv->brightness;
2009209ff23fSmrg    else if((attribute == xvSaturation) || (attribute == xvColor))
2010209ff23fSmrg	*value = pPriv->saturation;
2011209ff23fSmrg    else if(attribute == xvContrast)
2012209ff23fSmrg	*value = pPriv->contrast;
2013209ff23fSmrg    else if(attribute == xvHue)
2014209ff23fSmrg	*value = pPriv->hue;
2015209ff23fSmrg    else if(attribute == xvRedIntensity)
2016209ff23fSmrg	*value = pPriv->red_intensity;
2017209ff23fSmrg    else if(attribute == xvGreenIntensity)
2018209ff23fSmrg	*value = pPriv->green_intensity;
2019209ff23fSmrg    else if(attribute == xvBlueIntensity)
2020209ff23fSmrg	*value = pPriv->blue_intensity;
2021209ff23fSmrg    else if(attribute == xvGamma)
2022209ff23fSmrg	*value = pPriv->gamma;
2023209ff23fSmrg    else if(attribute == xvColorspace)
2024209ff23fSmrg	*value = pPriv->transform_index;
2025209ff23fSmrg    else if(attribute == xvDoubleBuffer)
2026209ff23fSmrg	*value = pPriv->doubleBuffer ? 1 : 0;
2027209ff23fSmrg    else if(attribute == xvColorKey)
2028209ff23fSmrg	*value = pPriv->colorKey;
2029209ff23fSmrg    else if(attribute == xvCRTC) {
2030209ff23fSmrg	int		c;
2031209ff23fSmrg	xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2032209ff23fSmrg	for (c = 0; c < xf86_config->num_crtc; c++)
2033209ff23fSmrg	    if (xf86_config->crtc[c] == pPriv->desired_crtc)
2034209ff23fSmrg		break;
2035209ff23fSmrg	if (c == xf86_config->num_crtc)
2036209ff23fSmrg	    c = -1;
2037209ff23fSmrg	*value = c;
2038209ff23fSmrg    }
2039209ff23fSmrg    else if(attribute == xvOvAlpha)
2040209ff23fSmrg	*value = pPriv->ov_alpha;
2041209ff23fSmrg    else if(attribute == xvGrAlpha)
2042209ff23fSmrg	*value = pPriv->gr_alpha;
2043209ff23fSmrg    else if(attribute == xvAlphaMode)
2044209ff23fSmrg	*value = pPriv->alpha_mode;
2045209ff23fSmrg    else if(attribute == xvDecBrightness)
2046209ff23fSmrg        *value = pPriv->dec_brightness;
2047209ff23fSmrg    else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
2048209ff23fSmrg        *value = pPriv->dec_saturation;
2049209ff23fSmrg    else if(attribute == xvDecContrast)
2050209ff23fSmrg        *value = pPriv->dec_contrast;
2051209ff23fSmrg    else if(attribute == xvDecHue)
2052209ff23fSmrg        *value = pPriv->dec_hue;
2053209ff23fSmrg    else if(attribute == xvEncoding)
2054209ff23fSmrg        *value = pPriv->encoding;
2055209ff23fSmrg    else if(attribute == xvFrequency)
2056209ff23fSmrg        *value = pPriv->frequency;
2057209ff23fSmrg    else
2058209ff23fSmrg    if(attribute == xvTunerStatus) {
2059209ff23fSmrg        if(pPriv->fi1236==NULL){
2060209ff23fSmrg                *value=TUNER_OFF;
2061209ff23fSmrg                } else
2062209ff23fSmrg                {
2063209ff23fSmrg                *value = xf86_TUNER_get_afc_hint(pPriv->fi1236);
2064209ff23fSmrg                }
2065209ff23fSmrg       }
2066209ff23fSmrg    else if(attribute == xvMute)
2067209ff23fSmrg        *value = pPriv->mute;
2068209ff23fSmrg    else if(attribute == xvSAP)
2069209ff23fSmrg        *value = pPriv->sap_channel;
2070209ff23fSmrg    else if(attribute == xvVolume)
2071209ff23fSmrg        *value = pPriv->volume;
2072209ff23fSmrg    else if(attribute == xvOverlayDeinterlacingMethod)
2073209ff23fSmrg        *value = pPriv->overlay_deinterlacing_method;
2074209ff23fSmrg    else if(attribute == xvDeviceID)
2075209ff23fSmrg        *value = pPriv->device_id;
2076209ff23fSmrg    else if(attribute == xvLocationID)
2077209ff23fSmrg        *value = pPriv->location_id;
2078209ff23fSmrg    else if(attribute == xvInstanceID)
2079209ff23fSmrg        *value = pPriv->instance_id;
2080209ff23fSmrg    else if(attribute == xvAdjustment)
2081209ff23fSmrg  	*value = pPriv->adjustment;
2082209ff23fSmrg    else
2083209ff23fSmrg	return BadMatch;
2084209ff23fSmrg
2085209ff23fSmrg    return Success;
2086209ff23fSmrg}
2087209ff23fSmrg
2088209ff23fSmrgvoid
2089209ff23fSmrgRADEONQueryBestSize(
2090209ff23fSmrg  ScrnInfoPtr pScrn,
2091209ff23fSmrg  Bool motion,
2092209ff23fSmrg  short vid_w, short vid_h,
2093209ff23fSmrg  short drw_w, short drw_h,
2094209ff23fSmrg  unsigned int *p_w, unsigned int *p_h,
2095209ff23fSmrg  pointer data
2096209ff23fSmrg){
2097209ff23fSmrg    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
2098209ff23fSmrg
2099209ff23fSmrg    if (!pPriv->textured) {
2100209ff23fSmrg	if (vid_w > (drw_w << 4))
2101209ff23fSmrg	    drw_w = vid_w >> 4;
2102209ff23fSmrg	if (vid_h > (drw_h << 4))
2103209ff23fSmrg	    drw_h = vid_h >> 4;
2104209ff23fSmrg    }
2105209ff23fSmrg
2106209ff23fSmrg  *p_w = drw_w;
2107209ff23fSmrg  *p_h = drw_h;
2108209ff23fSmrg}
2109209ff23fSmrg
2110209ff23fSmrgstatic struct {
2111209ff23fSmrg	double range;
2112209ff23fSmrg	signed char coeff[5][4];
2113209ff23fSmrg	} TapCoeffs[]=
2114209ff23fSmrg	{
2115209ff23fSmrg        {0.25, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13,   13,    3}, }},
2116209ff23fSmrg        {0.26, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2117209ff23fSmrg        {0.27, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2118209ff23fSmrg        {0.28, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2119209ff23fSmrg        {0.29, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2120209ff23fSmrg        {0.30, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2121209ff23fSmrg        {0.31, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2122209ff23fSmrg        {0.32, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2123209ff23fSmrg        {0.33, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2124209ff23fSmrg        {0.34, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2125209ff23fSmrg        {0.35, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2126209ff23fSmrg        {0.36, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2127209ff23fSmrg        {0.37, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2128209ff23fSmrg        {0.38, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2129209ff23fSmrg        {0.39, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2130209ff23fSmrg        {0.40, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2131209ff23fSmrg        {0.41, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2132209ff23fSmrg        {0.42, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2133209ff23fSmrg        {0.43, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2134209ff23fSmrg        {0.44, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2135209ff23fSmrg        {0.45, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2136209ff23fSmrg        {0.46, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2137209ff23fSmrg        {0.47, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2138209ff23fSmrg        {0.48, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2139209ff23fSmrg        {0.49, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2140209ff23fSmrg        {0.50, {{ 7,    16,  9,  0}, { 7,   16,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 3,   13, 13,  3}, }},
2141209ff23fSmrg        {0.51, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   15, 11,  1}, { 4,   15, 12,  1}, { 2,   14, 14,  2}, }},
2142209ff23fSmrg        {0.52, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
2143209ff23fSmrg        {0.53, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 5,   16, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
2144209ff23fSmrg        {0.54, {{ 7,    17,  8,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 2,   14, 14,  2}, }},
2145209ff23fSmrg        {0.55, {{ 7,    18,  7,  0}, { 6,   17,  9,  0}, { 4,   17, 11,  0}, { 3,   15, 13,  1}, { 1,   15, 15,  1}, }},
2146209ff23fSmrg        {0.56, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2147209ff23fSmrg        {0.57, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2148209ff23fSmrg        {0.58, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2149209ff23fSmrg        {0.59, {{ 7,    18,  7,  0}, { 5,   18,  9,  0}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2150209ff23fSmrg        {0.60, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2151209ff23fSmrg        {0.61, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2152209ff23fSmrg        {0.62, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2153209ff23fSmrg        {0.63, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 11,  0}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2154209ff23fSmrg        {0.64, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 1,   15, 15,  1}, }},
2155209ff23fSmrg        {0.65, {{ 7,    18,  8, -1}, { 6,   17, 10, -1}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
2156209ff23fSmrg        {0.66, {{ 7,    18,  8, -1}, { 6,   18, 10, -2}, { 4,   17, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
2157209ff23fSmrg        {0.67, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   18, 12, -1}, { 2,   17, 13,  0}, { 0,   16, 16,  0}, }},
2158209ff23fSmrg        {0.68, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
2159209ff23fSmrg        {0.69, {{ 7,    20,  7, -2}, { 5,   19, 10, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
2160209ff23fSmrg        {0.70, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
2161209ff23fSmrg        {0.71, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 3,   19, 12, -2}, { 1,   18, 14, -1}, { 0,   16, 16,  0}, }},
2162209ff23fSmrg        {0.72, {{ 7,    20,  7, -2}, { 5,   20,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
2163209ff23fSmrg        {0.73, {{ 7,    20,  7, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
2164209ff23fSmrg        {0.74, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 2,   20, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
2165209ff23fSmrg        {0.75, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
2166209ff23fSmrg        {0.76, {{ 6,    22,  6, -2}, { 4,   21,  9, -2}, { 1,   21, 12, -2}, { 0,   19, 15, -2}, {-1,   17, 17, -1}, }},
2167209ff23fSmrg        {0.77, {{ 6,    22,  6, -2}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
2168209ff23fSmrg        {0.78, {{ 6,    21,  6, -1}, { 3,   22,  9, -2}, { 1,   22, 12, -3}, { 0,   19, 15, -2}, {-2,   18, 18, -2}, }},
2169209ff23fSmrg        {0.79, {{ 5,    23,  5, -1}, { 3,   22,  9, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
2170209ff23fSmrg        {0.80, {{ 5,    23,  5, -1}, { 3,   23,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
2171209ff23fSmrg        {0.81, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-2,   18, 18, -2}, }},
2172209ff23fSmrg        {0.82, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 12, -3}, {-1,   21, 15, -3}, {-3,   19, 19, -3}, }},
2173209ff23fSmrg        {0.83, {{ 5,    23,  5, -1}, { 2,   24,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
2174209ff23fSmrg        {0.84, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
2175209ff23fSmrg        {0.85, {{ 4,    25,  4, -1}, { 1,   25,  8, -2}, { 0,   23, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
2176209ff23fSmrg        {0.86, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
2177209ff23fSmrg        {0.87, {{ 4,    24,  4,  0}, { 1,   25,  7, -1}, {-1,   24, 11, -2}, {-2,   22, 15, -3}, {-3,   19, 19, -3}, }},
2178209ff23fSmrg        {0.88, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
2179209ff23fSmrg        {0.89, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-1,   24, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
2180209ff23fSmrg        {0.90, {{ 3,    26,  3,  0}, { 0,   26,  7, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
2181209ff23fSmrg        {0.91, {{ 3,    26,  3,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
2182209ff23fSmrg        {0.92, {{ 2,    28,  2,  0}, { 0,   27,  6, -1}, {-2,   25, 11, -2}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
2183209ff23fSmrg        {0.93, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
2184209ff23fSmrg        {0.94, {{ 2,    28,  2,  0}, { 0,   26,  6,  0}, {-2,   25, 10, -1}, {-3,   23, 15, -3}, {-3,   19, 19, -3}, }},
2185209ff23fSmrg        {0.95, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
2186209ff23fSmrg        {0.96, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
2187209ff23fSmrg        {0.97, {{ 1,    30,  1,  0}, {-1,   28,  5,  0}, {-3,   26, 10, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
2188209ff23fSmrg        {0.98, {{ 1,    30,  1,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-3,   23, 14, -2}, {-3,   19, 19, -3}, }},
2189209ff23fSmrg        {0.99, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }},
2190209ff23fSmrg        {1.00, {{ 0,    32,  0,  0}, {-2,   29,  5,  0}, {-3,   27,  9, -1}, {-4,   24, 14, -2}, {-3,   19, 19, -3}, }}
2191209ff23fSmrg    };
2192209ff23fSmrg
2193209ff23fSmrgvoid
2194209ff23fSmrgRADEONCopyData(
2195209ff23fSmrg  ScrnInfoPtr pScrn,
2196209ff23fSmrg  unsigned char *src,
2197209ff23fSmrg  unsigned char *dst,
2198209ff23fSmrg  unsigned int srcPitch,
2199209ff23fSmrg  unsigned int dstPitch,
2200209ff23fSmrg  unsigned int h,
2201209ff23fSmrg  unsigned int w,
2202209ff23fSmrg  unsigned int bpp
2203209ff23fSmrg){
2204209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
2205209ff23fSmrg
2206209ff23fSmrg    /* Get the byte-swapping right for big endian systems */
2207209ff23fSmrg    if ( bpp == 2 ) {
2208209ff23fSmrg	w *= 2;
2209209ff23fSmrg	bpp = 1;
2210209ff23fSmrg    }
2211209ff23fSmrg
2212209ff23fSmrg#ifdef XF86DRI
2213209ff23fSmrg
2214209ff23fSmrg    if ( info->directRenderingEnabled && info->DMAForXv )
2215209ff23fSmrg    {
2216209ff23fSmrg	uint8_t *buf;
2217209ff23fSmrg	uint32_t bufPitch, dstPitchOff;
2218209ff23fSmrg	int x, y;
2219209ff23fSmrg	unsigned int hpass;
2220209ff23fSmrg
2221209ff23fSmrg	RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y );
2222209ff23fSmrg
2223209ff23fSmrg	while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch,
2224209ff23fSmrg					   x, &y, &h, &hpass )) )
2225209ff23fSmrg	{
2226209ff23fSmrg	    RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch,
2227209ff23fSmrg					srcPitch );
2228209ff23fSmrg	    src += hpass * srcPitch;
2229209ff23fSmrg	}
2230209ff23fSmrg
2231209ff23fSmrg	FLUSH_RING();
2232209ff23fSmrg
2233209ff23fSmrg	return;
2234209ff23fSmrg    }
2235209ff23fSmrg    else
2236209ff23fSmrg#endif /* XF86DRI */
2237209ff23fSmrg    {
2238ad43ddacSmrg	int swap = RADEON_HOST_DATA_SWAP_NONE;
2239ad43ddacSmrg
2240209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
2241ad43ddacSmrg	if (info->kms_enabled) {
2242ad43ddacSmrg	    switch(bpp) {
2243ad43ddacSmrg	    case 2:
2244ad43ddacSmrg		swap = RADEON_HOST_DATA_SWAP_16BIT;
2245ad43ddacSmrg		break;
2246ad43ddacSmrg	    case 4:
2247ad43ddacSmrg		swap = RADEON_HOST_DATA_SWAP_32BIT;
2248ad43ddacSmrg		break;
2249ad43ddacSmrg	    }
22500974d292Smrg	} else {
22510974d292Smrg	    switch (pScrn->bitsPerPixel) {
22520974d292Smrg	    case 16:
22530974d292Smrg		swap = RADEON_HOST_DATA_SWAP_16BIT;
22540974d292Smrg		break;
22550974d292Smrg	    case 32:
2256ad43ddacSmrg		swap = RADEON_HOST_DATA_SWAP_32BIT;
22570974d292Smrg		break;
22580974d292Smrg	    }
2259209ff23fSmrg	}
2260209ff23fSmrg#endif
2261ad43ddacSmrg
2262209ff23fSmrg	w *= bpp;
2263209ff23fSmrg
2264ad43ddacSmrg	if (dstPitch == w && dstPitch == srcPitch)
2265ad43ddacSmrg	    RADEONCopySwap(dst, src, h * dstPitch, swap);
2266ad43ddacSmrg	else {
2267ad43ddacSmrg	    while (h--) {
2268ad43ddacSmrg		RADEONCopySwap(dst, src, w, swap);
2269ad43ddacSmrg		src += srcPitch;
2270ad43ddacSmrg		dst += dstPitch;
2271ad43ddacSmrg	    }
2272209ff23fSmrg	}
2273209ff23fSmrg    }
2274209ff23fSmrg}
2275209ff23fSmrg
2276209ff23fSmrgstatic void
2277209ff23fSmrgRADEONCopyRGB24Data(
2278209ff23fSmrg  ScrnInfoPtr pScrn,
2279209ff23fSmrg  unsigned char *src,
2280209ff23fSmrg  unsigned char *dst,
2281209ff23fSmrg  unsigned int srcPitch,
2282209ff23fSmrg  unsigned int dstPitch,
2283209ff23fSmrg  unsigned int h,
2284209ff23fSmrg  unsigned int w
2285209ff23fSmrg){
2286209ff23fSmrg    uint32_t *dptr;
2287209ff23fSmrg    uint8_t *sptr;
2288209ff23fSmrg    int i,j;
2289209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
2290209ff23fSmrg#ifdef XF86DRI
2291209ff23fSmrg
2292209ff23fSmrg    if ( info->directRenderingEnabled && info->DMAForXv )
2293209ff23fSmrg    {
2294209ff23fSmrg	uint32_t bufPitch, dstPitchOff;
2295209ff23fSmrg	int x, y;
2296209ff23fSmrg	unsigned int hpass;
2297209ff23fSmrg
2298209ff23fSmrg	RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y );
2299209ff23fSmrg
2300209ff23fSmrg	while ( (dptr = ( uint32_t* )RADEONHostDataBlit( pScrn, 4, w, dstPitchOff,
2301209ff23fSmrg						       &bufPitch, x, &y, &h,
2302209ff23fSmrg						       &hpass )) )
2303209ff23fSmrg	{
2304209ff23fSmrg	    for( j = 0; j < hpass; j++ )
2305209ff23fSmrg	    {
2306209ff23fSmrg		sptr = src;
2307209ff23fSmrg
2308209ff23fSmrg		for ( i = 0 ; i < w; i++, sptr += 3 )
2309209ff23fSmrg		{
2310209ff23fSmrg		    dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0];
2311209ff23fSmrg		}
2312209ff23fSmrg
2313209ff23fSmrg		src += srcPitch;
2314209ff23fSmrg		dptr += bufPitch / 4;
2315209ff23fSmrg	    }
2316209ff23fSmrg	}
2317209ff23fSmrg
2318209ff23fSmrg	FLUSH_RING();
2319209ff23fSmrg
2320209ff23fSmrg	return;
2321209ff23fSmrg    }
2322209ff23fSmrg    else
2323209ff23fSmrg#endif /* XF86DRI */
2324209ff23fSmrg    {
2325209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
2326209ff23fSmrg	unsigned char *RADEONMMIO = info->MMIO;
2327ad43ddacSmrg
2328ad43ddacSmrg	if (!info->kms_enabled)
2329ad43ddacSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
2330ad43ddacSmrg		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
2331209ff23fSmrg#endif
2332209ff23fSmrg
2333209ff23fSmrg	for (j = 0; j < h; j++) {
2334209ff23fSmrg	    dptr = (uint32_t *)(dst + j * dstPitch);
2335209ff23fSmrg	    sptr = src + j * srcPitch;
2336209ff23fSmrg
2337209ff23fSmrg	    for (i = 0; i < w; i++, sptr += 3) {
2338ad43ddacSmrg		dptr[i] = cpu_to_le32((sptr[2] << 16) | (sptr[1] << 8) | sptr[0]);
2339209ff23fSmrg	    }
2340209ff23fSmrg	}
2341209ff23fSmrg
2342209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
2343ad43ddacSmrg	if (!info->kms_enabled) {
2344ad43ddacSmrg	    /* restore byte swapping */
2345ad43ddacSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
2346ad43ddacSmrg	}
2347209ff23fSmrg#endif
2348209ff23fSmrg    }
2349209ff23fSmrg}
2350209ff23fSmrg
2351209ff23fSmrg
2352209ff23fSmrg#ifdef XF86DRI
2353209ff23fSmrgstatic void RADEON_420_422(
2354209ff23fSmrg    unsigned int *d,
2355209ff23fSmrg    unsigned char *s1,
2356209ff23fSmrg    unsigned char *s2,
2357209ff23fSmrg    unsigned char *s3,
2358209ff23fSmrg    unsigned int n
2359209ff23fSmrg)
2360209ff23fSmrg{
2361209ff23fSmrg    while ( n ) {
2362209ff23fSmrg	*(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
2363209ff23fSmrg	s1+=2; s2++; s3++;
2364209ff23fSmrg	n--;
2365209ff23fSmrg    }
2366209ff23fSmrg}
2367209ff23fSmrg#endif
2368209ff23fSmrg
2369209ff23fSmrgvoid
2370209ff23fSmrgRADEONCopyMungedData(
2371209ff23fSmrg   ScrnInfoPtr pScrn,
2372209ff23fSmrg   unsigned char *src1,
2373209ff23fSmrg   unsigned char *src2,
2374209ff23fSmrg   unsigned char *src3,
2375209ff23fSmrg   unsigned char *dst1,
2376209ff23fSmrg   unsigned int srcPitch,
2377209ff23fSmrg   unsigned int srcPitch2,
2378209ff23fSmrg   unsigned int dstPitch,
2379209ff23fSmrg   unsigned int h,
2380209ff23fSmrg   unsigned int w
2381209ff23fSmrg){
2382209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
2383209ff23fSmrg#ifdef XF86DRI
2384209ff23fSmrg
2385209ff23fSmrg    if ( info->directRenderingEnabled && info->DMAForXv )
2386209ff23fSmrg    {
2387209ff23fSmrg	uint8_t *buf;
2388209ff23fSmrg	uint32_t y = 0, bufPitch, dstPitchOff;
2389209ff23fSmrg	int blitX, blitY;
2390209ff23fSmrg	unsigned int hpass;
2391209ff23fSmrg
2392209ff23fSmrg	/* XXX Fix endian flip on R300 */
2393209ff23fSmrg
2394209ff23fSmrg	RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY );
2395209ff23fSmrg
2396209ff23fSmrg	while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch,
2397209ff23fSmrg					   blitX, &blitY, &h, &hpass )) )
2398209ff23fSmrg	{
2399209ff23fSmrg	    while ( hpass-- )
2400209ff23fSmrg	    {
2401209ff23fSmrg		RADEON_420_422( (unsigned int *) buf, src1, src2, src3,
2402209ff23fSmrg				bufPitch / 4 );
2403209ff23fSmrg		src1 += srcPitch;
2404209ff23fSmrg		if ( y & 1 )
2405209ff23fSmrg		{
2406209ff23fSmrg		    src2 += srcPitch2;
2407209ff23fSmrg		    src3 += srcPitch2;
2408209ff23fSmrg		}
2409209ff23fSmrg		buf += bufPitch;
2410209ff23fSmrg		y++;
2411209ff23fSmrg	    }
2412209ff23fSmrg	}
2413209ff23fSmrg
2414209ff23fSmrg	FLUSH_RING();
2415209ff23fSmrg    }
2416209ff23fSmrg    else
2417209ff23fSmrg#endif /* XF86DRI */
2418209ff23fSmrg    {
2419209ff23fSmrg	uint32_t *dst;
2420209ff23fSmrg	uint8_t *s1, *s2, *s3;
2421209ff23fSmrg	int i, j;
2422209ff23fSmrg
2423209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
2424209ff23fSmrg	unsigned char *RADEONMMIO = info->MMIO;
2425ad43ddacSmrg
2426ad43ddacSmrg	if (!info->kms_enabled)
2427ad43ddacSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl &
2428ad43ddacSmrg		   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP));
2429209ff23fSmrg#endif
2430209ff23fSmrg
2431209ff23fSmrg	w /= 2;
2432209ff23fSmrg
2433209ff23fSmrg	for( j = 0; j < h; j++ )
2434209ff23fSmrg	{
2435209ff23fSmrg	    dst = (pointer)dst1;
2436209ff23fSmrg	    s1 = src1;  s2 = src2;  s3 = src3;
2437209ff23fSmrg	    i = w;
2438209ff23fSmrg	    while( i > 4 )
2439209ff23fSmrg	    {
2440ad43ddacSmrg		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
2441ad43ddacSmrg		dst[1] = cpu_to_le32(s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24));
2442ad43ddacSmrg		dst[2] = cpu_to_le32(s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24));
2443ad43ddacSmrg		dst[3] = cpu_to_le32(s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24));
2444209ff23fSmrg		dst += 4; s2 += 4; s3 += 4; s1 += 8;
2445209ff23fSmrg		i -= 4;
2446209ff23fSmrg	    }
2447209ff23fSmrg	    while( i-- )
2448209ff23fSmrg	    {
2449ad43ddacSmrg		dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24));
2450209ff23fSmrg		dst++; s2++; s3++;
2451209ff23fSmrg		s1 += 2;
2452209ff23fSmrg	    }
2453209ff23fSmrg
2454209ff23fSmrg	    dst1 += dstPitch;
2455209ff23fSmrg	    src1 += srcPitch;
2456209ff23fSmrg	    if( j & 1 )
2457209ff23fSmrg	    {
2458209ff23fSmrg		src2 += srcPitch2;
2459209ff23fSmrg		src3 += srcPitch2;
2460209ff23fSmrg	    }
2461209ff23fSmrg	}
2462209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
2463ad43ddacSmrg	if (!info->kms_enabled) {
2464ad43ddacSmrg	    /* restore byte swapping */
2465ad43ddacSmrg	    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
2466ad43ddacSmrg	}
2467209ff23fSmrg#endif
2468209ff23fSmrg    }
2469209ff23fSmrg}
2470209ff23fSmrg
2471209ff23fSmrgstatic void
2472209ff23fSmrgRADEONDisplayVideo(
2473209ff23fSmrg    ScrnInfoPtr pScrn,
2474209ff23fSmrg    xf86CrtcPtr crtc,
2475209ff23fSmrg    RADEONPortPrivPtr pPriv,
2476209ff23fSmrg    int id,
2477b7e1c893Smrg    int base_offset,
2478209ff23fSmrg    int offset1, int offset2,
2479209ff23fSmrg    int offset3, int offset4,
2480209ff23fSmrg    int offset5, int offset6,
2481209ff23fSmrg    short width, short height,
2482209ff23fSmrg    int pitch,
2483209ff23fSmrg    int left, int right, int top,
2484209ff23fSmrg    BoxPtr dstBox,
2485209ff23fSmrg    short src_w, short src_h,
2486209ff23fSmrg    short drw_w, short drw_h,
2487209ff23fSmrg    int deinterlacing_method
2488209ff23fSmrg){
2489209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
2490209ff23fSmrg    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2491209ff23fSmrg    unsigned char *RADEONMMIO = info->MMIO;
2492209ff23fSmrg    uint32_t v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp;
2493209ff23fSmrg    double h_inc_d;
2494209ff23fSmrg    int p1_h_accum_init, p23_h_accum_init;
2495209ff23fSmrg    int p1_v_accum_init, p23_v_accum_init;
2496209ff23fSmrg    int p23_blank_lines;
2497209ff23fSmrg    int ecp_div;
2498209ff23fSmrg    int v_inc_shift;
2499209ff23fSmrg    int y_mult;
2500209ff23fSmrg    int x_off;
2501209ff23fSmrg    int y_off;
2502209ff23fSmrg    uint32_t scaler_src;
2503209ff23fSmrg    uint32_t dot_clock;
2504209ff23fSmrg    int is_rgb;
2505209ff23fSmrg    int is_planar;
2506209ff23fSmrg    int i;
2507209ff23fSmrg    uint32_t scale_cntl;
2508209ff23fSmrg    double dsr;
2509209ff23fSmrg    int tap_set;
2510209ff23fSmrg    int predownscale=0;
2511209ff23fSmrg    int src_w_d;
2512209ff23fSmrg    int leftuv = 0;
2513209ff23fSmrg    DisplayModePtr mode;
2514209ff23fSmrg    RADEONOutputPrivatePtr radeon_output;
2515209ff23fSmrg    xf86OutputPtr output;
2516209ff23fSmrg    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
2517209ff23fSmrg
2518209ff23fSmrg    is_rgb=0; is_planar=0;
2519209ff23fSmrg    switch(id){
2520209ff23fSmrg        case FOURCC_I420:
2521209ff23fSmrg        case FOURCC_YV12:
2522209ff23fSmrg            is_planar=1;
2523209ff23fSmrg            break;
2524209ff23fSmrg        case FOURCC_RGBA32:
2525209ff23fSmrg        case FOURCC_RGB24:
2526209ff23fSmrg        case FOURCC_RGBT16:
2527209ff23fSmrg        case FOURCC_RGB16:
2528209ff23fSmrg            is_rgb=1;
2529209ff23fSmrg            break;
2530209ff23fSmrg        default:
2531209ff23fSmrg	    break;
2532209ff23fSmrg    }
2533209ff23fSmrg
2534209ff23fSmrg    /* Here we need to find ecp_div again, as the user may have switched resolutions
2535209ff23fSmrg       but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to
2536209ff23fSmrg       workarounds for chip erratas */
2537209ff23fSmrg
2538209ff23fSmrg    /* Figure out which head we are on for dot clock */
2539209ff23fSmrg    if (radeon_crtc->crtc_id == 1)
2540209ff23fSmrg        dot_clock = info->ModeReg->dot_clock_freq_2;
2541209ff23fSmrg    else
2542209ff23fSmrg        dot_clock = info->ModeReg->dot_clock_freq;
2543209ff23fSmrg
2544209ff23fSmrg    if (dot_clock < 17500)
2545209ff23fSmrg        ecp_div = 0;
2546209ff23fSmrg    else
2547209ff23fSmrg	ecp_div = 1;
2548209ff23fSmrg
2549209ff23fSmrg    if (ecp_div != info->ecp_div) {
2550209ff23fSmrg	info->ecp_div = ecp_div;
2551209ff23fSmrg	OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
2552209ff23fSmrg	   (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
2553209ff23fSmrg    }
2554209ff23fSmrg
2555209ff23fSmrg    /* I suspect we may need a usleep after writing to the PLL.  if you play a video too soon
2556209ff23fSmrg       after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
2557209ff23fSmrg       on the right edge video output.
2558209ff23fSmrg       Is this still the case? Might have been chips which need the errata,
2559209ff23fSmrg       there is now plenty of usleep after INPLL/OUTPLL for those...*/
2560209ff23fSmrg
2561209ff23fSmrg    v_inc_shift = 20;
2562209ff23fSmrg    y_mult = 1;
2563209ff23fSmrg
2564209ff23fSmrg    mode = &crtc->mode;
2565209ff23fSmrg
2566209ff23fSmrg    if (mode->Flags & V_INTERLACE)
2567209ff23fSmrg	v_inc_shift++;
2568209ff23fSmrg    if (mode->Flags & V_DBLSCAN) {
2569209ff23fSmrg	v_inc_shift--;
2570209ff23fSmrg	y_mult = 2;
2571209ff23fSmrg    }
2572209ff23fSmrg
2573209ff23fSmrg    v_inc = (src_h << v_inc_shift) / drw_h;
2574209ff23fSmrg
2575209ff23fSmrg    for (i = 0; i < xf86_config->num_output; i++) {
2576209ff23fSmrg	output = xf86_config->output[i];
2577209ff23fSmrg	if (output->crtc == crtc) {
2578209ff23fSmrg	    radeon_output = output->driver_private;
2579209ff23fSmrg	    if (radeon_output->Flags & RADEON_USE_RMX)
2580209ff23fSmrg		v_inc = ((src_h * mode->CrtcVDisplay /
2581b7e1c893Smrg			  radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h;
2582209ff23fSmrg	    break;
2583209ff23fSmrg	}
2584209ff23fSmrg    }
2585209ff23fSmrg
2586209ff23fSmrg    h_inc = (1 << (12 + ecp_div));
2587209ff23fSmrg
2588209ff23fSmrg    step_by_y = 1;
2589209ff23fSmrg    step_by_uv = step_by_y;
2590209ff23fSmrg
2591209ff23fSmrg    src_w_d = src_w;
2592209ff23fSmrg#if 0
2593209ff23fSmrg    /* XXX this does not appear to work */
2594209ff23fSmrg    /* if the source width was larger than what would fit in overlay scaler increase step_by values */
2595209ff23fSmrg    i=src_w;
2596209ff23fSmrg    while(i>info->overlay_scaler_buffer_width){
2597209ff23fSmrg	step_by_y++;
2598209ff23fSmrg	step_by_uv++;
2599209ff23fSmrg	h_inc >>=1;
2600209ff23fSmrg	i=i/2;
2601209ff23fSmrg	}
2602209ff23fSmrg#else
2603209ff23fSmrg    /* predownscale instead (yes this hurts quality) - will only work for widths up
2604209ff23fSmrg       to 2 times the overlay_scaler_buffer_width, should be enough */
2605209ff23fSmrg    if (src_w_d > info->overlay_scaler_buffer_width) {
2606209ff23fSmrg	src_w_d /= 2; /* odd widths? */
2607209ff23fSmrg	predownscale = 1;
2608209ff23fSmrg    }
2609209ff23fSmrg#endif
2610209ff23fSmrg
2611209ff23fSmrg    h_inc_d = src_w_d;
2612209ff23fSmrg    h_inc_d = h_inc_d/drw_w;
2613209ff23fSmrg    /* we could do a tad better  - but why
2614209ff23fSmrg       bother when this concerns downscaling and the code is so much more
2615209ff23fSmrg       hairy */
2616209ff23fSmrg    while(h_inc*h_inc_d >= (2 << 12)) {
2617209ff23fSmrg        if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){
2618209ff23fSmrg                step_by_uv = step_by_y+1;
2619209ff23fSmrg                break;
2620209ff23fSmrg                }
2621209ff23fSmrg        step_by_y++;
2622209ff23fSmrg        step_by_uv = step_by_y;
2623209ff23fSmrg        h_inc >>= 1;
2624209ff23fSmrg    }
2625209ff23fSmrg
2626209ff23fSmrg    h_inc_uv = h_inc>>(step_by_uv-step_by_y);
2627209ff23fSmrg    h_inc = h_inc * h_inc_d;
2628209ff23fSmrg    h_inc_uv = h_inc_uv * h_inc_d;
2629209ff23fSmrg    /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit
2630209ff23fSmrg       in the buffer for 2 tap filtering */
2631209ff23fSmrg    /* the only place it is documented in is in ATI source code */
2632209ff23fSmrg    /* we need twice as much space for 4 tap filtering.. */
2633209ff23fSmrg    /* under special circumstances turn on 4 tap filtering */
2634209ff23fSmrg    /* disable this code for now as it has a DISASTROUS effect on image quality when upscaling
2635209ff23fSmrg       at least on rv250 (only as long as the drw_w*2 <=... requirement is still met of course) */
2636209ff23fSmrg#if 0
2637209ff23fSmrg    if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12))
2638209ff23fSmrg       && (deinterlacing_method!=METHOD_WEAVE)
2639209ff23fSmrg       && (drw_w*2 <= info->overlay_scaler_buffer_width)){
2640209ff23fSmrg        step_by_y=0;
2641209ff23fSmrg        step_by_uv=1;
2642209ff23fSmrg        h_inc_uv = h_inc;
2643209ff23fSmrg        }
2644209ff23fSmrg#endif
2645209ff23fSmrg
2646b7e1c893Smrg    /* Make the overlay base address as close to the buffers as possible to
2647b7e1c893Smrg     * prevent the buffer offsets from exceeding the hardware limit of 128 MB.
2648b7e1c893Smrg     * The base address must be aligned to a multiple of 4 MB.
2649b7e1c893Smrg     */
2650b7e1c893Smrg    base_offset = ((info->fbLocation + base_offset) & (~0 << 22)) -
2651b7e1c893Smrg	info->fbLocation;
2652b7e1c893Smrg
2653b7e1c893Smrg    offset1 -= base_offset;
2654b7e1c893Smrg    offset2 -= base_offset;
2655b7e1c893Smrg    offset3 -= base_offset;
2656b7e1c893Smrg    offset4 -= base_offset;
2657b7e1c893Smrg    offset5 -= base_offset;
2658b7e1c893Smrg    offset6 -= base_offset;
2659b7e1c893Smrg
2660209ff23fSmrg    /* keep everything in 16.16 */
2661209ff23fSmrg
2662209ff23fSmrg    if (is_planar) {
2663209ff23fSmrg	offset1 += ((left >> 16) & ~15);
2664209ff23fSmrg	offset2 += ((left >> 16) & ~31) >> 1;
2665209ff23fSmrg	offset3 += ((left >> 16) & ~31) >> 1;
2666209ff23fSmrg	offset4 += ((left >> 16) & ~15);
2667209ff23fSmrg	offset5 += ((left >> 16) & ~31) >> 1;
2668209ff23fSmrg	offset6 += ((left >> 16) & ~31) >> 1;
2669209ff23fSmrg	offset2 |= RADEON_VIF_BUF0_PITCH_SEL;
2670209ff23fSmrg	offset3 |= RADEON_VIF_BUF0_PITCH_SEL;
2671209ff23fSmrg	offset5 |= RADEON_VIF_BUF0_PITCH_SEL;
2672209ff23fSmrg	offset6 |= RADEON_VIF_BUF0_PITCH_SEL;
2673209ff23fSmrg    }
2674209ff23fSmrg    else {
2675209ff23fSmrg	/* is this really correct for non-2-byte formats? */
2676209ff23fSmrg	offset1 += ((left >> 16) & ~7) << 1;
2677209ff23fSmrg	offset2 += ((left >> 16) & ~7) << 1;
2678209ff23fSmrg	offset3 += ((left >> 16) & ~7) << 1;
2679209ff23fSmrg	offset4 += ((left >> 16) & ~7) << 1;
2680209ff23fSmrg	offset5 += ((left >> 16) & ~7) << 1;
2681209ff23fSmrg	offset6 += ((left >> 16) & ~7) << 1;
2682209ff23fSmrg    }
2683209ff23fSmrg
2684209ff23fSmrg    tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
2685209ff23fSmrg    p1_h_accum_init = ((tmp <<  4) & 0x000f8000) |
2686209ff23fSmrg		      ((tmp << 12) & 0xf0000000);
2687209ff23fSmrg
2688209ff23fSmrg    tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2);
2689209ff23fSmrg    p23_h_accum_init = ((tmp <<  4) & 0x000f8000) |
2690209ff23fSmrg		       ((tmp << 12) & 0x70000000);
2691209ff23fSmrg
2692209ff23fSmrg    tmp = (top & 0x0000ffff) + 0x00018000;
2693209ff23fSmrg    p1_v_accum_init = ((tmp << 4) & 0x03ff8000) |
2694209ff23fSmrg    	(((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01);
2695209ff23fSmrg
2696209ff23fSmrg    if (is_planar) {
2697209ff23fSmrg	p23_v_accum_init = ((tmp << 4) & 0x03ff8000) |
2698209ff23fSmrg	    ((deinterlacing_method != METHOD_WEAVE) ? 0x03 : 0x01);
2699209ff23fSmrg	p23_blank_lines = (((src_h >> 1) - 1) << 16);
2700209ff23fSmrg    }
2701209ff23fSmrg    else {
2702209ff23fSmrg	p23_v_accum_init = 0;
2703209ff23fSmrg	p23_blank_lines = 0;
2704209ff23fSmrg    }
2705209ff23fSmrg
2706209ff23fSmrg    if (is_planar) {
2707209ff23fSmrg	leftuv = ((left >> 16) >> 1) & 15;
2708209ff23fSmrg	left = (left >> 16) & 15;
2709209ff23fSmrg    }
2710209ff23fSmrg    else {
2711209ff23fSmrg	left = (left >> 16) & 7;
2712209ff23fSmrg	if (!is_rgb)
2713209ff23fSmrg	    leftuv = left >> 1;
2714209ff23fSmrg    }
2715209ff23fSmrg
2716209ff23fSmrg    RADEONWaitForFifo(pScrn, 2);
2717209ff23fSmrg    OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK);
2718209ff23fSmrg    if (info->accelOn) RADEON_SYNC(info, pScrn);
2719209ff23fSmrg    while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
2720209ff23fSmrg
2721209ff23fSmrg    RADEONWaitForFifo(pScrn, 10);
2722209ff23fSmrg    OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16));
2723209ff23fSmrg    OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) |
2724209ff23fSmrg	predownscale << 4 | predownscale << 12);
2725209ff23fSmrg
2726209ff23fSmrg    x_off = 8;
2727209ff23fSmrg    y_off = 0;
2728209ff23fSmrg
2729209ff23fSmrg    if (IS_R300_VARIANT ||
2730209ff23fSmrg        (info->ChipFamily == CHIP_FAMILY_R200))
2731209ff23fSmrg	x_off = 0;
2732209ff23fSmrg
2733209ff23fSmrg    /* needed to make the overlay work on crtc1 in leftof and above modes */
2734209ff23fSmrg    /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */
2735209ff23fSmrg    /*
2736209ff23fSmrg    if (srel == radeonLeftOf) {
2737209ff23fSmrg	x_off -= mode->CrtcHDisplay;
2738209ff23fSmrg    }
2739209ff23fSmrg    if (srel == radeonAbove) {
2740209ff23fSmrg	y_off -= mode->CrtcVDisplay;
2741209ff23fSmrg    }
2742209ff23fSmrg    */
2743209ff23fSmrg
2744209ff23fSmrg    /* Put the hardware overlay on CRTC2:
2745209ff23fSmrg     *
2746209ff23fSmrg     * Since one hardware overlay can not be displayed on two heads
2747209ff23fSmrg     * at the same time, we might need to consider using software
2748209ff23fSmrg     * rendering for the second head.
2749209ff23fSmrg     */
2750209ff23fSmrg
2751209ff23fSmrg    if (radeon_crtc->crtc_id == 1) {
2752209ff23fSmrg        x_off = 0;
2753209ff23fSmrg        OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
2754209ff23fSmrg                                      ((dstBox->y1*y_mult) << 16)));
2755209ff23fSmrg        OUTREG(RADEON_OV1_Y_X_END,   ((dstBox->x2 + x_off) |
2756209ff23fSmrg                                      ((dstBox->y2*y_mult) << 16)));
2757209ff23fSmrg        scaler_src = RADEON_SCALER_CRTC_SEL;
2758209ff23fSmrg    } else {
2759209ff23fSmrg	OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) |
2760209ff23fSmrg				      (((dstBox->y1*y_mult) + y_off) << 16)));
2761209ff23fSmrg	OUTREG(RADEON_OV0_Y_X_END,   ((dstBox->x2 + x_off) |
2762209ff23fSmrg				      (((dstBox->y2*y_mult) + y_off) << 16)));
2763209ff23fSmrg	scaler_src = 0;
2764209ff23fSmrg    }
2765209ff23fSmrg
2766209ff23fSmrg    /* program the tap coefficients for better downscaling quality.
2767209ff23fSmrg       Could do slightly better by using hardcoded coefficients for one axis
2768209ff23fSmrg       in case only the other axis is downscaled (see RADEON_OV0_FILTER_CNTL) */
2769209ff23fSmrg    dsr=(double)(1<<0xC)/h_inc;
2770209ff23fSmrg    if(dsr<0.25)dsr=0.25;
2771209ff23fSmrg    if(dsr>1.0)dsr=1.0;
2772209ff23fSmrg    tap_set=(int)((dsr-0.25)*100);
2773209ff23fSmrg    for(i=0;i<5;i++){
2774209ff23fSmrg	    OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) |
2775209ff23fSmrg	    	((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) |
2776209ff23fSmrg	    	((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) |
2777209ff23fSmrg	    	((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24));
2778209ff23fSmrg		}
2779209ff23fSmrg
2780209ff23fSmrg    RADEONWaitForFifo(pScrn, 11);
2781209ff23fSmrg    OUTREG(RADEON_OV0_V_INC, v_inc);
2782209ff23fSmrg    OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));
2783209ff23fSmrg    OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | p23_blank_lines);
2784209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch);
2785209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch);
2786209ff23fSmrg    OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16));
2787209ff23fSmrg    if (!is_rgb)
2788209ff23fSmrg	src_w >>= 1;
2789209ff23fSmrg    OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
2790209ff23fSmrg    OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
2791b7e1c893Smrg    if (info->ModeReg->ov0_base_addr != (info->fbLocation + base_offset)) {
2792b7e1c893Smrg	ErrorF("Changing OV0_BASE_ADDR from 0x%08x to 0x%08x\n",
2793921a55d8Smrg	       info->ModeReg->ov0_base_addr, (uint32_t)info->fbLocation + base_offset);
2794b7e1c893Smrg	info->ModeReg->ov0_base_addr = info->fbLocation + base_offset;
2795b7e1c893Smrg	OUTREG(RADEON_OV0_BASE_ADDR, info->ModeReg->ov0_base_addr);
2796b7e1c893Smrg    }
2797209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1);
2798209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2);
2799209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3);
2800209ff23fSmrg
2801209ff23fSmrg    RADEONWaitForFifo(pScrn, 9);
2802209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4);
2803209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset5);
2804209ff23fSmrg    OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset6);
2805209ff23fSmrg    OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
2806209ff23fSmrg    OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
2807209ff23fSmrg    OUTREG(RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init);
2808209ff23fSmrg    OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
2809209ff23fSmrg
2810209ff23fSmrg   scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER
2811209ff23fSmrg        | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16) | scaler_src;
2812209ff23fSmrg   switch(id){
2813209ff23fSmrg        case FOURCC_UYVY:
2814209ff23fSmrg		scale_cntl |= RADEON_SCALER_SOURCE_YVYU422;
2815209ff23fSmrg		break;
2816209ff23fSmrg        case FOURCC_RGB24:
2817209ff23fSmrg        case FOURCC_RGBA32:
2818209ff23fSmrg		scale_cntl |= RADEON_SCALER_SOURCE_32BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
2819209ff23fSmrg		break;
2820209ff23fSmrg        case FOURCC_RGB16:
2821209ff23fSmrg		scale_cntl |= RADEON_SCALER_SOURCE_16BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
2822209ff23fSmrg		break;
2823209ff23fSmrg        case FOURCC_RGBT16:
2824209ff23fSmrg		scale_cntl |= RADEON_SCALER_SOURCE_15BPP | RADEON_SCALER_LIN_TRANS_BYPASS;
2825209ff23fSmrg		break;
2826209ff23fSmrg        case FOURCC_YV12:
2827209ff23fSmrg        case FOURCC_I420:
2828209ff23fSmrg		scale_cntl |= RADEON_SCALER_SOURCE_YUV12;
2829209ff23fSmrg		break;
2830209ff23fSmrg        case FOURCC_YUY2:
2831209ff23fSmrg        default:
2832209ff23fSmrg		scale_cntl |= RADEON_SCALER_SOURCE_VYUY422
2833209ff23fSmrg			| ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0);
2834209ff23fSmrg		break;
2835209ff23fSmrg    }
2836209ff23fSmrg
2837209ff23fSmrg    if (info->ChipFamily < CHIP_FAMILY_R200) {
2838209ff23fSmrg	scale_cntl &= ~RADEON_SCALER_GAMMA_SEL_MASK;
2839209ff23fSmrg	scale_cntl |= ((RADEONTranslateUserGamma(pPriv->gamma)) << 5);
2840209ff23fSmrg    }
2841209ff23fSmrg
2842209ff23fSmrg    OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl);
2843209ff23fSmrg    OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
2844209ff23fSmrg}
2845209ff23fSmrg
2846209ff23fSmrg
2847209ff23fSmrgstatic void
2848209ff23fSmrgRADEONFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes)
2849209ff23fSmrg{
2850209ff23fSmrg#if HAVE_XV_DRAWABLE_HELPER
2851209ff23fSmrg    xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes);
2852209ff23fSmrg#else
2853209ff23fSmrg    xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes);
2854209ff23fSmrg#endif
2855209ff23fSmrg}
2856209ff23fSmrg
2857209ff23fSmrg
2858209ff23fSmrgstatic int
2859209ff23fSmrgRADEONPutImage(
2860209ff23fSmrg  ScrnInfoPtr pScrn,
2861209ff23fSmrg  short src_x, short src_y,
2862209ff23fSmrg  short drw_x, short drw_y,
2863209ff23fSmrg  short src_w, short src_h,
2864209ff23fSmrg  short drw_w, short drw_h,
2865209ff23fSmrg  int id, unsigned char* buf,
2866209ff23fSmrg  short width, short height,
2867209ff23fSmrg  Bool Sync,
2868209ff23fSmrg  RegionPtr clipBoxes, pointer data,
2869209ff23fSmrg  DrawablePtr pDraw
2870209ff23fSmrg){
2871209ff23fSmrg   RADEONInfoPtr info = RADEONPTR(pScrn);
2872209ff23fSmrg   RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
2873209ff23fSmrg   INT32 xa, xb, ya, yb;
2874209ff23fSmrg   unsigned char *dst_start;
2875209ff23fSmrg   int new_size, offset, s2offset, s3offset;
2876209ff23fSmrg   int srcPitch, srcPitch2, dstPitch;
2877209ff23fSmrg   int d2line, d3line;
2878209ff23fSmrg   int top, left, npixels, nlines, bpp;
2879209ff23fSmrg   int idconv = id;
2880209ff23fSmrg   BoxRec dstBox;
2881209ff23fSmrg   uint32_t tmp;
2882209ff23fSmrg   xf86CrtcPtr crtc;
2883209ff23fSmrg
2884209ff23fSmrg   /*
2885209ff23fSmrg    * s2offset, s3offset - byte offsets into U and V plane of the
2886209ff23fSmrg    *                      source where copying starts.  Y plane is
2887209ff23fSmrg    *                      done by editing "buf".
2888209ff23fSmrg    *
2889209ff23fSmrg    * offset - byte offset to the first line of the destination.
2890209ff23fSmrg    *
2891209ff23fSmrg    * dst_start - byte address to the first displayed pel.
2892209ff23fSmrg    *
2893209ff23fSmrg    */
2894209ff23fSmrg
2895209ff23fSmrg   /* make the compiler happy */
2896209ff23fSmrg   s2offset = s3offset = srcPitch2 = 0;
2897209ff23fSmrg   d2line = d3line = 0;
2898209ff23fSmrg
2899209ff23fSmrg   if(src_w > (drw_w << 4))
2900209ff23fSmrg	drw_w = src_w >> 4;
2901209ff23fSmrg   if(src_h > (drw_h << 4))
2902209ff23fSmrg	drw_h = src_h >> 4;
2903209ff23fSmrg
2904209ff23fSmrg   /* Clip */
2905209ff23fSmrg   xa = src_x;
2906209ff23fSmrg   xb = src_x + src_w;
2907209ff23fSmrg   ya = src_y;
2908209ff23fSmrg   yb = src_y + src_h;
2909209ff23fSmrg
2910209ff23fSmrg   dstBox.x1 = drw_x;
2911209ff23fSmrg   dstBox.x2 = drw_x + drw_w;
2912209ff23fSmrg   dstBox.y1 = drw_y;
2913209ff23fSmrg   dstBox.y2 = drw_y + drw_h;
2914209ff23fSmrg
2915209ff23fSmrg   if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
2916209ff23fSmrg			       &dstBox, &xa, &xb, &ya, &yb,
2917209ff23fSmrg			       clipBoxes, width, height))
2918209ff23fSmrg       return Success;
2919209ff23fSmrg
2920209ff23fSmrg   if (!crtc) {
2921209ff23fSmrg       if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
2922209ff23fSmrg	   unsigned char *RADEONMMIO = info->MMIO;
2923209ff23fSmrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
2924209ff23fSmrg	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
2925209ff23fSmrg       }
2926209ff23fSmrg       return Success;
2927209ff23fSmrg   }
2928209ff23fSmrg
2929209ff23fSmrg   dstBox.x1 -= crtc->x;
2930209ff23fSmrg   dstBox.x2 -= crtc->x;
2931209ff23fSmrg   dstBox.y1 -= crtc->y;
2932209ff23fSmrg   dstBox.y2 -= crtc->y;
2933209ff23fSmrg
2934209ff23fSmrg   bpp = pScrn->bitsPerPixel >> 3;
2935209ff23fSmrg
2936209ff23fSmrg   switch(id) {
2937209ff23fSmrg   case FOURCC_RGB24:
2938209ff23fSmrg	dstPitch = width * 4;
2939209ff23fSmrg	srcPitch = width * 3;
2940209ff23fSmrg	break;
2941209ff23fSmrg   case FOURCC_RGBA32:
2942209ff23fSmrg	dstPitch = width * 4;
2943209ff23fSmrg	srcPitch = width * 4;
2944209ff23fSmrg	break;
2945209ff23fSmrg   case FOURCC_RGB16:
2946209ff23fSmrg   case FOURCC_RGBT16:
2947209ff23fSmrg	dstPitch = width * 2;
2948ad43ddacSmrg	srcPitch = RADEON_ALIGN(width * 2, 4);
2949209ff23fSmrg	break;
2950209ff23fSmrg   case FOURCC_YV12:
2951209ff23fSmrg   case FOURCC_I420:
2952209ff23fSmrg	/* it seems rs4xx chips (all of them???) either can't handle planar
2953209ff23fSmrg	   yuv at all or would need some unknown different setup. */
2954209ff23fSmrg       if ((info->ChipFamily != CHIP_FAMILY_RS400) &&
2955209ff23fSmrg	   (info->ChipFamily != CHIP_FAMILY_RS480)) {
2956209ff23fSmrg	    /* need 16bytes alignment for u,v plane, so 2 times that for width
2957209ff23fSmrg	       but blitter needs 64bytes alignment. 128byte is a waste but dstpitch
2958209ff23fSmrg	       for uv planes needs to be dstpitch yplane >> 1 for now. */
2959ad43ddacSmrg	    dstPitch = (RADEON_ALIGN(width, 128));
2960ad43ddacSmrg	    srcPitch = RADEON_ALIGN(width, 4);
2961209ff23fSmrg	}
2962209ff23fSmrg	else {
2963209ff23fSmrg	    dstPitch = width * 2;
2964ad43ddacSmrg	    srcPitch = RADEON_ALIGN(width, 4);
2965209ff23fSmrg	    idconv = FOURCC_YUY2;
2966209ff23fSmrg	}
2967209ff23fSmrg	break;
2968209ff23fSmrg   case FOURCC_UYVY:
2969209ff23fSmrg   case FOURCC_YUY2:
2970209ff23fSmrg   default:
2971209ff23fSmrg	dstPitch = width * 2;
2972209ff23fSmrg	srcPitch = width * 2;
2973209ff23fSmrg	break;
2974209ff23fSmrg   }
2975209ff23fSmrg
2976209ff23fSmrg#ifdef XF86DRI
2977209ff23fSmrg   if (info->directRenderingEnabled && info->DMAForXv) {
2978209ff23fSmrg       /* The upload blit only supports multiples of 64 bytes */
2979ad43ddacSmrg       dstPitch = RADEON_ALIGN(dstPitch, 64);
2980209ff23fSmrg   } else
2981209ff23fSmrg#endif
2982209ff23fSmrg       /* The overlay only supports multiples of 16 bytes */
2983ad43ddacSmrg       dstPitch = RADEON_ALIGN(dstPitch, 16);
2984209ff23fSmrg
2985209ff23fSmrg   new_size = dstPitch * height;
2986209ff23fSmrg   if (idconv == FOURCC_YV12 || id == FOURCC_I420) {
2987ad43ddacSmrg      new_size += (dstPitch >> 1) * (RADEON_ALIGN(height, 2));
2988209ff23fSmrg   }
2989b7e1c893Smrg   pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
2990b7e1c893Smrg						       (pPriv->doubleBuffer ?
2991ad43ddacSmrg						       (new_size * 2) : new_size), 64,
2992ad43ddacSmrg						       RADEON_GEM_DOMAIN_VRAM);
2993209ff23fSmrg   if (pPriv->video_offset == 0)
2994209ff23fSmrg      return BadAlloc;
2995209ff23fSmrg
2996209ff23fSmrg   pPriv->currentBuffer ^= 1;
2997209ff23fSmrg
2998209ff23fSmrg    /* copy data */
2999209ff23fSmrg   top = ya >> 16;
3000209ff23fSmrg   left = (xa >> 16) & ~1;
300140732134Srjs   npixels = ((xb + 0xffff) >> 16) - left;
3002209ff23fSmrg
3003209ff23fSmrg   offset = (pPriv->video_offset) + (top * dstPitch);
3004209ff23fSmrg
3005209ff23fSmrg   if(pPriv->doubleBuffer) {
3006209ff23fSmrg	unsigned char *RADEONMMIO = info->MMIO;
3007209ff23fSmrg
3008209ff23fSmrg	/* Wait for last flip to take effect */
3009209ff23fSmrg	while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK));
3010209ff23fSmrg
3011209ff23fSmrg	offset += pPriv->currentBuffer * new_size;
3012209ff23fSmrg   }
3013209ff23fSmrg
3014209ff23fSmrg   dst_start = info->FB + offset;
3015209ff23fSmrg
3016209ff23fSmrg   switch(id) {
3017209ff23fSmrg   case FOURCC_YV12:
3018209ff23fSmrg   case FOURCC_I420:
3019209ff23fSmrg	if (id == idconv) {
3020209ff23fSmrg	    /* meh. Such a mess just for someone who wants to watch half the video clipped */
3021209ff23fSmrg	    top &= ~1;
3022209ff23fSmrg	    /* odd number of pixels? That may not work correctly */
3023ad43ddacSmrg	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
3024209ff23fSmrg	    /* odd number of lines? Maybe... */
3025ad43ddacSmrg	    s2offset = srcPitch * (RADEON_ALIGN(height, 2));
3026209ff23fSmrg	    s3offset = s2offset + srcPitch2 * ((height + 1) >> 1);
3027209ff23fSmrg	    s2offset += (top >> 1) * srcPitch2 + (left >> 1);
3028209ff23fSmrg	    s3offset += (top >> 1) * srcPitch2 + (left >> 1);
3029209ff23fSmrg	    d2line = (height * dstPitch);
3030209ff23fSmrg	    d3line = d2line + ((height + 1) >> 1) * (dstPitch >> 1);
3031209ff23fSmrg	    nlines = ((yb + 0xffff) >> 16) - top;
3032209ff23fSmrg	    d2line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
3033209ff23fSmrg	    d3line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch);
3034209ff23fSmrg	    if(id == FOURCC_YV12) {
3035209ff23fSmrg		tmp = s2offset;
3036209ff23fSmrg		s2offset = s3offset;
3037209ff23fSmrg		s3offset = tmp;
3038209ff23fSmrg	    }
3039209ff23fSmrg	    RADEONCopyData(pScrn, buf + (top * srcPitch) + left, dst_start + left,
3040209ff23fSmrg		srcPitch, dstPitch, nlines, npixels, 1);
3041209ff23fSmrg	    RADEONCopyData(pScrn, buf + s2offset, dst_start + d2line + (left >> 1),
3042209ff23fSmrg		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
3043209ff23fSmrg	    RADEONCopyData(pScrn, buf + s3offset, dst_start + d3line + (left >> 1),
3044209ff23fSmrg		srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1);
3045209ff23fSmrg	}
3046209ff23fSmrg	else {
3047209ff23fSmrg	    s2offset = srcPitch * height;
3048ad43ddacSmrg	    srcPitch2 = RADEON_ALIGN(width >> 1, 4);
3049209ff23fSmrg	    s3offset = (srcPitch2 * (height >> 1)) + s2offset;
3050209ff23fSmrg	    top &= ~1;
3051209ff23fSmrg	    dst_start += left << 1;
3052209ff23fSmrg	    tmp = ((top >> 1) * srcPitch2) + (left >> 1);
3053209ff23fSmrg	    s2offset += tmp;
3054209ff23fSmrg	    s3offset += tmp;
3055209ff23fSmrg	    if(id == FOURCC_I420) {
3056209ff23fSmrg		tmp = s2offset;
3057209ff23fSmrg		s2offset = s3offset;
3058209ff23fSmrg		s3offset = tmp;
3059209ff23fSmrg	    }
306040732134Srjs	    nlines = ((yb + 0xffff) >> 16) - top;
3061209ff23fSmrg	    RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left,
3062209ff23fSmrg				 buf + s2offset, buf + s3offset, dst_start,
3063209ff23fSmrg				 srcPitch, srcPitch2, dstPitch, nlines, npixels);
3064209ff23fSmrg	}
3065209ff23fSmrg	break;
3066209ff23fSmrg    case FOURCC_RGBT16:
3067209ff23fSmrg    case FOURCC_RGB16:
3068209ff23fSmrg    case FOURCC_UYVY:
3069209ff23fSmrg    case FOURCC_YUY2:
3070209ff23fSmrg    default:
3071209ff23fSmrg	left <<= 1;
3072209ff23fSmrg	buf += (top * srcPitch) + left;
3073209ff23fSmrg	nlines = ((yb + 0xffff) >> 16) - top;
3074209ff23fSmrg	dst_start += left;
3075209ff23fSmrg	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2);
3076209ff23fSmrg	break;
3077209ff23fSmrg    case FOURCC_RGBA32:
3078209ff23fSmrg	buf += (top * srcPitch) + left*4;
3079209ff23fSmrg	nlines = ((yb + 0xffff) >> 16) - top;
3080209ff23fSmrg	dst_start += left*4;
3081209ff23fSmrg	RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4);
3082209ff23fSmrg    	break;
3083209ff23fSmrg    case FOURCC_RGB24:
3084209ff23fSmrg	buf += (top * srcPitch) + left*3;
3085209ff23fSmrg	nlines = ((yb + 0xffff) >> 16) - top;
3086209ff23fSmrg	dst_start += left*4;
3087209ff23fSmrg	RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels);
3088209ff23fSmrg    	break;
3089209ff23fSmrg    }
3090209ff23fSmrg
3091209ff23fSmrg    /* update cliplist */
3092209ff23fSmrg    if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
3093209ff23fSmrg    {
3094209ff23fSmrg	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
3095209ff23fSmrg	/* draw these */
3096209ff23fSmrg	if(pPriv->autopaint_colorkey)
3097209ff23fSmrg	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
3098209ff23fSmrg    }
3099209ff23fSmrg
3100209ff23fSmrg    /* FIXME: someone should look at these offsets, I don't think it makes sense how
3101209ff23fSmrg              they are handled throughout the source. */
3102b7e1c893Smrg    RADEONDisplayVideo(pScrn, crtc, pPriv, idconv, pPriv->video_offset, offset,
3103b7e1c893Smrg		       offset + d2line, offset + d3line, offset, offset + d2line,
3104b7e1c893Smrg		       offset + d3line, width, height, dstPitch, xa, xb, ya,
3105b7e1c893Smrg		       &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
3106209ff23fSmrg
3107209ff23fSmrg    pPriv->videoStatus = CLIENT_VIDEO_ON;
3108209ff23fSmrg
3109209ff23fSmrg    info->VideoTimerCallback = RADEONVideoTimerCallback;
3110209ff23fSmrg
3111209ff23fSmrg    return Success;
3112209ff23fSmrg}
3113209ff23fSmrg
3114209ff23fSmrg
3115209ff23fSmrgint
3116209ff23fSmrgRADEONQueryImageAttributes(
3117209ff23fSmrg    ScrnInfoPtr pScrn,
3118209ff23fSmrg    int id,
3119209ff23fSmrg    unsigned short *w, unsigned short *h,
3120209ff23fSmrg    int *pitches, int *offsets
3121209ff23fSmrg){
3122ad43ddacSmrg    const RADEONInfoRec * const info = RADEONPTR(pScrn);
3123209ff23fSmrg    int size, tmp;
3124209ff23fSmrg
3125ad43ddacSmrg    if(*w > info->xv_max_width) *w = info->xv_max_width;
3126ad43ddacSmrg    if(*h > info->xv_max_height) *h = info->xv_max_height;
3127209ff23fSmrg
3128ad43ddacSmrg    *w = RADEON_ALIGN(*w, 2);
3129209ff23fSmrg    if(offsets) offsets[0] = 0;
3130209ff23fSmrg
3131209ff23fSmrg    switch(id) {
3132209ff23fSmrg    case FOURCC_YV12:
3133209ff23fSmrg    case FOURCC_I420:
3134ad43ddacSmrg	*h = RADEON_ALIGN(*h, 2);
3135ad43ddacSmrg	size = RADEON_ALIGN(*w, 4);
3136209ff23fSmrg	if(pitches) pitches[0] = size;
3137209ff23fSmrg	size *= *h;
3138209ff23fSmrg	if(offsets) offsets[1] = size;
3139ad43ddacSmrg	tmp = RADEON_ALIGN(*w >> 1, 4);
3140209ff23fSmrg	if(pitches) pitches[1] = pitches[2] = tmp;
3141209ff23fSmrg	tmp *= (*h >> 1);
3142209ff23fSmrg	size += tmp;
3143209ff23fSmrg	if(offsets) offsets[2] = size;
3144209ff23fSmrg	size += tmp;
3145209ff23fSmrg	break;
3146209ff23fSmrg    case FOURCC_RGBA32:
3147209ff23fSmrg	size = *w << 2;
3148209ff23fSmrg	if(pitches) pitches[0] = size;
3149209ff23fSmrg	size *= *h;
3150209ff23fSmrg	break;
3151209ff23fSmrg    case FOURCC_RGB24:
3152209ff23fSmrg	size = *w * 3;
3153209ff23fSmrg	if(pitches) pitches[0] = size;
3154209ff23fSmrg	size *= *h;
3155209ff23fSmrg	break;
3156209ff23fSmrg    case FOURCC_RGBT16:
3157209ff23fSmrg    case FOURCC_RGB16:
3158209ff23fSmrg    case FOURCC_UYVY:
3159209ff23fSmrg    case FOURCC_YUY2:
3160209ff23fSmrg    default:
3161209ff23fSmrg	size = *w << 1;
3162209ff23fSmrg	if(pitches) pitches[0] = size;
3163209ff23fSmrg	size *= *h;
3164209ff23fSmrg	break;
3165209ff23fSmrg    }
3166209ff23fSmrg
3167209ff23fSmrg    return size;
3168209ff23fSmrg}
3169209ff23fSmrg
3170209ff23fSmrgstatic void
3171209ff23fSmrgRADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now)
3172209ff23fSmrg{
3173209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
3174209ff23fSmrg    RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
3175209ff23fSmrg
3176209ff23fSmrg    if(pPriv->videoStatus & TIMER_MASK) {
3177209ff23fSmrg	if(pPriv->videoStatus & OFF_TIMER) {
3178209ff23fSmrg	    if(pPriv->offTime < now) {
3179209ff23fSmrg		unsigned char *RADEONMMIO = info->MMIO;
3180209ff23fSmrg		OUTREG(RADEON_OV0_SCALE_CNTL, 0);
3181209ff23fSmrg		pPriv->videoStatus = FREE_TIMER;
3182209ff23fSmrg		pPriv->freeTime = now + FREE_DELAY;
3183209ff23fSmrg	    }
3184209ff23fSmrg	} else {  /* FREE_TIMER */
3185209ff23fSmrg	    if(pPriv->freeTime < now) {
3186921a55d8Smrg		RADEONFreeVideoMemory(pScrn, pPriv);
3187209ff23fSmrg		pPriv->videoStatus = 0;
3188209ff23fSmrg		info->VideoTimerCallback = NULL;
3189209ff23fSmrg	    }
3190209ff23fSmrg	}
3191209ff23fSmrg    } else  /* shouldn't get here */
3192209ff23fSmrg	info->VideoTimerCallback = NULL;
3193209ff23fSmrg}
3194209ff23fSmrg
3195209ff23fSmrg/****************** Offscreen stuff ***************/
3196209ff23fSmrgtypedef struct {
3197209ff23fSmrg  void *surface_memory;
3198209ff23fSmrg  Bool isOn;
3199209ff23fSmrg} OffscreenPrivRec, * OffscreenPrivPtr;
3200209ff23fSmrg
3201209ff23fSmrgstatic int
3202209ff23fSmrgRADEONAllocateSurface(
3203209ff23fSmrg    ScrnInfoPtr pScrn,
3204209ff23fSmrg    int id,
3205209ff23fSmrg    unsigned short w,
3206209ff23fSmrg    unsigned short h,
3207209ff23fSmrg    XF86SurfacePtr surface
3208209ff23fSmrg){
3209209ff23fSmrg    int offset, pitch, size;
3210209ff23fSmrg    OffscreenPrivPtr pPriv;
3211209ff23fSmrg    void *surface_memory = NULL;
3212209ff23fSmrg    if((w > 1024) || (h > 1024))
3213209ff23fSmrg	return BadAlloc;
3214209ff23fSmrg
3215ad43ddacSmrg    w = RADEON_ALIGN(w, 2);
3216ad43ddacSmrg    pitch = RADEON_ALIGN(w << 1, 16);
3217209ff23fSmrg    size = pitch * h;
3218209ff23fSmrg
3219ad43ddacSmrg    offset = radeon_legacy_allocate_memory(pScrn, &surface_memory, size, 64,
3220ad43ddacSmrg		    RADEON_GEM_DOMAIN_VRAM);
3221209ff23fSmrg    if (offset == 0)
3222209ff23fSmrg	return BadAlloc;
3223209ff23fSmrg
3224209ff23fSmrg    surface->width = w;
3225209ff23fSmrg    surface->height = h;
3226209ff23fSmrg
32272f39173dSmrg    if(!(surface->pitches = malloc(sizeof(int)))) {
3228b7e1c893Smrg	radeon_legacy_free_memory(pScrn, surface_memory);
3229209ff23fSmrg	return BadAlloc;
3230209ff23fSmrg    }
32312f39173dSmrg    if(!(surface->offsets = malloc(sizeof(int)))) {
32322f39173dSmrg	free(surface->pitches);
3233b7e1c893Smrg	radeon_legacy_free_memory(pScrn, surface_memory);
3234209ff23fSmrg	return BadAlloc;
3235209ff23fSmrg    }
32362f39173dSmrg    if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) {
32372f39173dSmrg	free(surface->pitches);
32382f39173dSmrg	free(surface->offsets);
3239b7e1c893Smrg	radeon_legacy_free_memory(pScrn, surface_memory);
3240209ff23fSmrg	return BadAlloc;
3241209ff23fSmrg    }
3242209ff23fSmrg
3243209ff23fSmrg    pPriv->surface_memory = surface_memory;
3244209ff23fSmrg    pPriv->isOn = FALSE;
3245209ff23fSmrg
3246209ff23fSmrg    surface->pScrn = pScrn;
3247209ff23fSmrg    surface->id = id;
3248209ff23fSmrg    surface->pitches[0] = pitch;
3249209ff23fSmrg    surface->offsets[0] = offset;
3250209ff23fSmrg    surface->devPrivate.ptr = (pointer)pPriv;
3251209ff23fSmrg
3252209ff23fSmrg    return Success;
3253209ff23fSmrg}
3254209ff23fSmrg
3255209ff23fSmrgstatic int
3256209ff23fSmrgRADEONStopSurface(
3257209ff23fSmrg    XF86SurfacePtr surface
3258209ff23fSmrg){
3259209ff23fSmrg  OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
3260209ff23fSmrg  RADEONInfoPtr info = RADEONPTR(surface->pScrn);
3261209ff23fSmrg  unsigned char *RADEONMMIO = info->MMIO;
3262209ff23fSmrg
3263209ff23fSmrg  if(pPriv->isOn) {
3264209ff23fSmrg	OUTREG(RADEON_OV0_SCALE_CNTL, 0);
3265209ff23fSmrg	pPriv->isOn = FALSE;
3266209ff23fSmrg  }
3267209ff23fSmrg  return Success;
3268209ff23fSmrg}
3269209ff23fSmrg
3270209ff23fSmrg
3271209ff23fSmrgstatic int
3272209ff23fSmrgRADEONFreeSurface(
3273209ff23fSmrg    XF86SurfacePtr surface
3274209ff23fSmrg){
3275209ff23fSmrg    ScrnInfoPtr pScrn = surface->pScrn;
3276209ff23fSmrg    OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
3277209ff23fSmrg
3278209ff23fSmrg    if(pPriv->isOn)
3279209ff23fSmrg	RADEONStopSurface(surface);
3280b7e1c893Smrg    radeon_legacy_free_memory(pScrn, pPriv->surface_memory);
3281b7e1c893Smrg    pPriv->surface_memory = NULL;
32822f39173dSmrg    free(surface->pitches);
32832f39173dSmrg    free(surface->offsets);
32842f39173dSmrg    free(surface->devPrivate.ptr);
3285209ff23fSmrg
3286209ff23fSmrg    return Success;
3287209ff23fSmrg}
3288209ff23fSmrg
3289209ff23fSmrgstatic int
3290209ff23fSmrgRADEONGetSurfaceAttribute(
3291209ff23fSmrg    ScrnInfoPtr pScrn,
3292209ff23fSmrg    Atom attribute,
3293209ff23fSmrg    INT32 *value
3294209ff23fSmrg){
3295209ff23fSmrg   return RADEONGetPortAttribute(pScrn, attribute, value,
3296209ff23fSmrg		(pointer)(GET_PORT_PRIVATE(pScrn)));
3297209ff23fSmrg}
3298209ff23fSmrg
3299209ff23fSmrgstatic int
3300209ff23fSmrgRADEONSetSurfaceAttribute(
3301209ff23fSmrg    ScrnInfoPtr pScrn,
3302209ff23fSmrg    Atom attribute,
3303209ff23fSmrg    INT32 value
3304209ff23fSmrg){
3305209ff23fSmrg   return RADEONSetPortAttribute(pScrn, attribute, value,
3306209ff23fSmrg		(pointer)(GET_PORT_PRIVATE(pScrn)));
3307209ff23fSmrg}
3308209ff23fSmrg
3309209ff23fSmrg
3310209ff23fSmrgstatic int
3311209ff23fSmrgRADEONDisplaySurface(
3312209ff23fSmrg    XF86SurfacePtr surface,
3313209ff23fSmrg    short src_x, short src_y,
3314209ff23fSmrg    short drw_x, short drw_y,
3315209ff23fSmrg    short src_w, short src_h,
3316209ff23fSmrg    short drw_w, short drw_h,
3317209ff23fSmrg    RegionPtr clipBoxes
3318209ff23fSmrg){
3319209ff23fSmrg    OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
3320209ff23fSmrg    ScrnInfoPtr pScrn = surface->pScrn;
3321209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn);
3322209ff23fSmrg    RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
3323209ff23fSmrg
3324209ff23fSmrg    INT32 xa, ya, xb, yb;
3325209ff23fSmrg    BoxRec dstBox;
3326209ff23fSmrg    xf86CrtcPtr crtc;
3327209ff23fSmrg
3328209ff23fSmrg    if (src_w > (drw_w << 4))
3329209ff23fSmrg	drw_w = src_w >> 4;
3330209ff23fSmrg    if (src_h > (drw_h << 4))
3331209ff23fSmrg	drw_h = src_h >> 4;
3332209ff23fSmrg
3333209ff23fSmrg    xa = src_x;
3334209ff23fSmrg    xb = src_x + src_w;
3335209ff23fSmrg    ya = src_y;
3336209ff23fSmrg    yb = src_y + src_h;
3337209ff23fSmrg
3338209ff23fSmrg    dstBox.x1 = drw_x;
3339209ff23fSmrg    dstBox.x2 = drw_x + drw_w;
3340209ff23fSmrg    dstBox.y1 = drw_y;
3341209ff23fSmrg    dstBox.y2 = drw_y + drw_h;
3342209ff23fSmrg
3343209ff23fSmrg    if (!radeon_crtc_clip_video(pScrn, &crtc, portPriv->desired_crtc,
3344209ff23fSmrg				&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
3345209ff23fSmrg				surface->width, surface->height))
3346209ff23fSmrg        return Success;
3347209ff23fSmrg
3348209ff23fSmrg   if (!crtc) {
3349209ff23fSmrg       if (pPriv->isOn) {
3350209ff23fSmrg	   unsigned char *RADEONMMIO = info->MMIO;
3351209ff23fSmrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
3352209ff23fSmrg	   pPriv->isOn = FALSE;
3353209ff23fSmrg       }
3354209ff23fSmrg       return Success;
3355209ff23fSmrg   }
3356209ff23fSmrg
3357209ff23fSmrg    dstBox.x1 -= crtc->x;
3358209ff23fSmrg    dstBox.x2 -= crtc->x;
3359209ff23fSmrg    dstBox.y1 -= crtc->y;
3360209ff23fSmrg    dstBox.y2 -= crtc->y;
3361209ff23fSmrg
3362209ff23fSmrg#if 0
3363209ff23fSmrg    /* this isn't needed */
3364209ff23fSmrg    RADEONResetVideo(pScrn);
3365209ff23fSmrg#endif
3366209ff23fSmrg    RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id,
3367209ff23fSmrg		       surface->offsets[0], surface->offsets[0],
3368209ff23fSmrg		       surface->offsets[0], surface->offsets[0],
3369209ff23fSmrg		       surface->offsets[0], surface->offsets[0],
3370b7e1c893Smrg		       surface->offsets[0], surface->width, surface->height,
3371b7e1c893Smrg		       surface->pitches[0], xa, xb, ya, &dstBox, src_w, src_h,
3372b7e1c893Smrg		       drw_w, drw_h, METHOD_BOB);
3373209ff23fSmrg
3374209ff23fSmrg    if (portPriv->autopaint_colorkey)
3375209ff23fSmrg	xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
3376209ff23fSmrg
3377209ff23fSmrg    pPriv->isOn = TRUE;
3378209ff23fSmrg    /* we've prempted the XvImage stream so set its free timer */
3379209ff23fSmrg    if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
3380209ff23fSmrg	REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
3381209ff23fSmrg	UpdateCurrentTime();
3382209ff23fSmrg	portPriv->videoStatus = FREE_TIMER;
3383209ff23fSmrg	portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
3384209ff23fSmrg	info->VideoTimerCallback = RADEONVideoTimerCallback;
3385209ff23fSmrg    }
3386209ff23fSmrg
3387209ff23fSmrg    return Success;
3388209ff23fSmrg}
3389209ff23fSmrg
3390209ff23fSmrg
3391209ff23fSmrgstatic void
3392209ff23fSmrgRADEONInitOffscreenImages(ScreenPtr pScreen)
3393209ff23fSmrg{
3394209ff23fSmrg/*  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
3395209ff23fSmrg    RADEONInfoPtr info = RADEONPTR(pScrn); */
3396209ff23fSmrg    XF86OffscreenImagePtr offscreenImages;
3397209ff23fSmrg    /* need to free this someplace */
3398209ff23fSmrg
33992f39173dSmrg    if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec))))
3400209ff23fSmrg	return;
3401209ff23fSmrg
3402209ff23fSmrg    offscreenImages[0].image = &Images[0];
3403209ff23fSmrg    offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*|
3404209ff23fSmrg			       VIDEO_CLIP_TO_VIEWPORT*/;
3405209ff23fSmrg    offscreenImages[0].alloc_surface = RADEONAllocateSurface;
3406209ff23fSmrg    offscreenImages[0].free_surface = RADEONFreeSurface;
3407209ff23fSmrg    offscreenImages[0].display = RADEONDisplaySurface;
3408209ff23fSmrg    offscreenImages[0].stop = RADEONStopSurface;
3409209ff23fSmrg    offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute;
3410209ff23fSmrg    offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute;
3411921a55d8Smrg    offscreenImages[0].max_width = 2047;
3412921a55d8Smrg    offscreenImages[0].max_height = 2047;
3413209ff23fSmrg    offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
3414209ff23fSmrg    offscreenImages[0].attributes = Attributes;
3415209ff23fSmrg
3416209ff23fSmrg    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
3417209ff23fSmrg}
3418209ff23fSmrg
3419209ff23fSmrg         /* TV-in functions */
3420209ff23fSmrg
3421209ff23fSmrgstatic int
3422209ff23fSmrgRADEONPutVideo(
3423209ff23fSmrg  ScrnInfoPtr pScrn,
3424209ff23fSmrg  short src_x, short src_y,
3425209ff23fSmrg  short drw_x, short drw_y,
3426209ff23fSmrg  short src_w, short src_h,
3427209ff23fSmrg  short drw_w, short drw_h,
3428209ff23fSmrg  RegionPtr clipBoxes, pointer data,
3429209ff23fSmrg  DrawablePtr pDraw
3430209ff23fSmrg){
3431209ff23fSmrg   RADEONInfoPtr info = RADEONPTR(pScrn);
3432209ff23fSmrg   RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
3433209ff23fSmrg   unsigned char *RADEONMMIO = info->MMIO;
3434209ff23fSmrg   INT32 xa, xb, ya, yb, top;
3435209ff23fSmrg   unsigned int pitch, new_size, alloc_size;
3436209ff23fSmrg   unsigned int offset1, offset2, offset3, offset4, s2offset, s3offset;
3437209ff23fSmrg   unsigned int vbi_offset0, vbi_offset1;
3438209ff23fSmrg   int srcPitch, srcPitch2, dstPitch;
3439209ff23fSmrg   int bpp;
3440209ff23fSmrg   BoxRec dstBox;
3441209ff23fSmrg   uint32_t id, display_base;
3442209ff23fSmrg   int width, height;
3443209ff23fSmrg   int mult;
3444209ff23fSmrg   int vbi_line_width, vbi_start, vbi_end;
3445209ff23fSmrg   xf86CrtcPtr crtc;
3446209ff23fSmrg
3447209ff23fSmrg    RADEON_SYNC(info, pScrn);
3448209ff23fSmrg   /*
3449209ff23fSmrg    * s2offset, s3offset - byte offsets into U and V plane of the
3450209ff23fSmrg    *                      source where copying starts.  Y plane is
3451209ff23fSmrg    *                      done by editing "buf".
3452209ff23fSmrg    *
3453209ff23fSmrg    * offset - byte offset to the first line of the destination.
3454209ff23fSmrg    *
3455209ff23fSmrg    * dst_start - byte address to the first displayed pel.
3456209ff23fSmrg    *
3457209ff23fSmrg    */
3458209ff23fSmrg
3459209ff23fSmrg   /* make the compiler happy */
3460209ff23fSmrg   s2offset = s3offset = srcPitch2 = 0;
3461209ff23fSmrg
3462209ff23fSmrg   if(src_w > (drw_w << 4))
3463209ff23fSmrg        drw_w = src_w >> 4;
3464209ff23fSmrg   if(src_h > (drw_h << 4))
3465209ff23fSmrg        drw_h = src_h >> 4;
3466209ff23fSmrg
3467209ff23fSmrg   /* Clip */
3468209ff23fSmrg   xa = src_x;
3469209ff23fSmrg   xb = src_x + src_w;
3470209ff23fSmrg   ya = src_y;
3471209ff23fSmrg   yb = src_y + src_h;
3472209ff23fSmrg
3473209ff23fSmrg   dstBox.x1 = drw_x;
3474209ff23fSmrg   dstBox.x2 = drw_x + drw_w;
3475209ff23fSmrg   dstBox.y1 = drw_y;
3476209ff23fSmrg   dstBox.y2 = drw_y + drw_h;
3477209ff23fSmrg
3478209ff23fSmrg   width = InputVideoEncodings[pPriv->encoding].width;
3479209ff23fSmrg   height = InputVideoEncodings[pPriv->encoding].height;
3480209ff23fSmrg
3481209ff23fSmrg   vbi_line_width = 798*2;
3482209ff23fSmrg   if(width<=640)
3483209ff23fSmrg       vbi_line_width = 0x640; /* 1600 actually */
3484209ff23fSmrg   else
3485209ff23fSmrg       vbi_line_width = 2000; /* might need adjustment */
3486209ff23fSmrg
3487209ff23fSmrg   if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc,
3488209ff23fSmrg			       &dstBox, &xa, &xb, &ya, &yb,
3489209ff23fSmrg			       clipBoxes, width, height))
3490209ff23fSmrg       return Success;
3491209ff23fSmrg
3492209ff23fSmrg   if (!crtc) {
3493209ff23fSmrg       if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
3494209ff23fSmrg	   unsigned char *RADEONMMIO = info->MMIO;
3495209ff23fSmrg	   OUTREG(RADEON_OV0_SCALE_CNTL, 0);
3496209ff23fSmrg	   pPriv->videoStatus &= ~CLIENT_VIDEO_ON;
3497209ff23fSmrg       }
3498209ff23fSmrg       return Success;
3499209ff23fSmrg   }
3500209ff23fSmrg
3501209ff23fSmrg   dstBox.x1 -= crtc->x;
3502209ff23fSmrg   dstBox.x2 -= crtc->x;
3503209ff23fSmrg   dstBox.y1 -= crtc->y;
3504209ff23fSmrg   dstBox.y2 -= crtc->y;
3505209ff23fSmrg
3506209ff23fSmrg   bpp = pScrn->bitsPerPixel >> 3;
3507209ff23fSmrg   pitch = bpp * pScrn->displayWidth;
3508209ff23fSmrg
3509209ff23fSmrg   switch(pPriv->overlay_deinterlacing_method){
3510209ff23fSmrg        case METHOD_BOB:
3511209ff23fSmrg        case METHOD_SINGLE:
3512209ff23fSmrg                mult=2;
3513209ff23fSmrg                break;
3514209ff23fSmrg        case METHOD_WEAVE:
3515209ff23fSmrg        case METHOD_ADAPTIVE:
3516209ff23fSmrg                mult=4;
3517209ff23fSmrg                break;
3518209ff23fSmrg        default:
3519209ff23fSmrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n");
3520209ff23fSmrg                mult=4;
3521209ff23fSmrg        }
3522209ff23fSmrg
3523209ff23fSmrg   id = FOURCC_YUY2;
3524209ff23fSmrg
3525209ff23fSmrg   top = ya>>16;
3526209ff23fSmrg#if 0
3527209ff23fSmrg   /* setting the ID above makes this useful - needs revisiting */
3528209ff23fSmrg   switch(id) {
3529209ff23fSmrg   case FOURCC_YV12:
3530209ff23fSmrg   case FOURCC_I420:
3531209ff23fSmrg        top &= ~1;
3532ad43ddacSmrg        dstPitch = RADEON_ALIGN(width << 1, 16);
3533ad43ddacSmrg        srcPitch = RADEON_ALIGN(width, 4);
3534209ff23fSmrg        s2offset = srcPitch * height;
3535ad43ddacSmrg        srcPitch2 = RADEON_ALIGN(width >> 1, 4);
3536209ff23fSmrg        s3offset = (srcPitch2 * (height >> 1)) + s2offset;
3537209ff23fSmrg        break;
3538209ff23fSmrg   case FOURCC_UYVY:
3539209ff23fSmrg   case FOURCC_YUY2:
3540209ff23fSmrg   default:
3541ad43ddacSmrg        dstPitch = RADEON_ALIGN(width<<1, 16);
3542209ff23fSmrg        srcPitch = (width<<1);
3543209ff23fSmrg        break;
3544209ff23fSmrg   }
3545209ff23fSmrg#else
3546ad43ddacSmrg   dstPitch = RADEON_ALIGN(width << 1, 16);
3547209ff23fSmrg   srcPitch = (width<<1);
3548209ff23fSmrg#endif
3549209ff23fSmrg
3550209ff23fSmrg   new_size = dstPitch * height;
3551209ff23fSmrg   new_size = new_size + 0x1f; /* for aligning */
3552209ff23fSmrg   alloc_size = new_size * mult;
3553209ff23fSmrg   if (pPriv->capture_vbi_data)
3554209ff23fSmrg      alloc_size += 2 * 2 * vbi_line_width * 21;
3555209ff23fSmrg
3556b7e1c893Smrg   pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory,
3557b7e1c893Smrg						      (pPriv->doubleBuffer ?
3558ad43ddacSmrg						      (new_size * 2) : new_size), 64,
3559ad43ddacSmrg						      RADEON_GEM_DOMAIN_GTT);
3560209ff23fSmrg   if (pPriv->video_offset == 0)
3561209ff23fSmrg      return BadAlloc;
3562209ff23fSmrg
3563209ff23fSmrg/* I have suspicion that capture engine must be active _before_ Rage Theatre
3564209ff23fSmrg   is being manipulated with.. */
3565209ff23fSmrg
3566209ff23fSmrg   RADEONWaitForIdleMMIO(pScrn);
3567209ff23fSmrg   display_base=INREG(RADEON_DISPLAY_BASE_ADDR);
3568209ff23fSmrg
3569209ff23fSmrg/*   RADEONWaitForFifo(pScrn, 15); */
3570209ff23fSmrg
3571209ff23fSmrg   switch(pPriv->overlay_deinterlacing_method){
3572209ff23fSmrg        case METHOD_BOB:
3573209ff23fSmrg        case METHOD_SINGLE:
3574ad43ddacSmrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
3575ad43ddacSmrg           offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
3576209ff23fSmrg           offset3 = offset1;
3577209ff23fSmrg           offset4 = offset2;
3578209ff23fSmrg           break;
3579209ff23fSmrg        case METHOD_WEAVE:
3580ad43ddacSmrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
3581209ff23fSmrg           offset2 = offset1+dstPitch;
3582ad43ddacSmrg           offset3 = RADEON_ALIGN(pPriv->video_offset + 2 * new_size, 0x10);
3583209ff23fSmrg           offset4 = offset3+dstPitch;
3584209ff23fSmrg           break;
3585209ff23fSmrg        default:
3586ad43ddacSmrg           offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10);
3587ad43ddacSmrg           offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10);
3588209ff23fSmrg           offset3 = offset1;
3589209ff23fSmrg           offset4 = offset2;
3590209ff23fSmrg        }
3591209ff23fSmrg
3592209ff23fSmrg   OUTREG(RADEON_CAP0_BUF0_OFFSET,        offset1+display_base);
3593209ff23fSmrg   OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET,   offset2+display_base);
3594209ff23fSmrg   OUTREG(RADEON_CAP0_BUF1_OFFSET,        offset3+display_base);
3595209ff23fSmrg   OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET,   offset4+display_base);
3596209ff23fSmrg
3597209ff23fSmrg   OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base);
3598209ff23fSmrg
3599209ff23fSmrg   if(pPriv->capture_vbi_data){
3600209ff23fSmrg        if ((pPriv->encoding==2)||(pPriv->encoding==8)) {
3601209ff23fSmrg            /* PAL, SECAM */
3602209ff23fSmrg            vbi_start = 5;
3603209ff23fSmrg            vbi_end = 21;
3604209ff23fSmrg        } else {
3605209ff23fSmrg            /* NTSC */
3606209ff23fSmrg            vbi_start = 8;
3607209ff23fSmrg            vbi_end = 20;
3608209ff23fSmrg        }
3609209ff23fSmrg
3610ad43ddacSmrg        vbi_offset0 = RADEON_ALIGN(pPriv->video_offset + mult * new_size * bpp, 0x10);
3611209ff23fSmrg        vbi_offset1 = vbi_offset0 + dstPitch*20;
3612209ff23fSmrg        OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base);
3613209ff23fSmrg        OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base);
3614209ff23fSmrg        OUTREG(RADEON_CAP0_VBI2_OFFSET, 0);
3615209ff23fSmrg        OUTREG(RADEON_CAP0_VBI3_OFFSET, 0);
3616209ff23fSmrg        OUTREG(RADEON_CAP0_VBI_V_WINDOW, vbi_start | (vbi_end<<16));
3617209ff23fSmrg        OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16);
3618209ff23fSmrg        }
3619209ff23fSmrg
3620209ff23fSmrg   OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2);
3621209ff23fSmrg   OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16);
3622209ff23fSmrg   OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1));
3623209ff23fSmrg   if(mult==2){
3624209ff23fSmrg           OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB);
3625209ff23fSmrg           } else {
3626209ff23fSmrg           OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE);
3627209ff23fSmrg           }
3628209ff23fSmrg   OUTREG(RADEON_CAP0_DEBUG, 0);
3629209ff23fSmrg
3630209ff23fSmrg   OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01);
3631209ff23fSmrg   OUTREG(RADEON_TEST_DEBUG_CNTL, 0);
3632209ff23fSmrg
3633209ff23fSmrg   if(! pPriv->video_stream_active)
3634209ff23fSmrg   {
3635209ff23fSmrg
3636209ff23fSmrg      RADEONWaitForIdleMMIO(pScrn);
3637209ff23fSmrg      OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 );
3638209ff23fSmrg      OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0);
3639209ff23fSmrg      OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK);
3640209ff23fSmrg      OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11);
3641209ff23fSmrg      if(pPriv->theatre != NULL)
3642209ff23fSmrg      {
3643209ff23fSmrg         RADEON_RT_SetEncoding(pScrn, pPriv);
3644209ff23fSmrg      }
3645209ff23fSmrg      if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
3646209ff23fSmrg      if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
3647209ff23fSmrg      if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
3648209ff23fSmrg      if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
3649209ff23fSmrg   }
3650209ff23fSmrg
3651209ff23fSmrg
3652209ff23fSmrg   /* update cliplist */
3653209ff23fSmrg   if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
3654209ff23fSmrg        REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
3655209ff23fSmrg        /* draw these */
3656209ff23fSmrg        if(pPriv->autopaint_colorkey)
3657209ff23fSmrg	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
3658209ff23fSmrg   }
3659209ff23fSmrg
3660b7e1c893Smrg   RADEONDisplayVideo(pScrn, crtc, pPriv, id, pPriv->video_offset,
3661b7e1c893Smrg		      offset1+top*srcPitch, offset2+top*srcPitch,
3662b7e1c893Smrg		      offset3+top*srcPitch, offset4+top*srcPitch,
3663b7e1c893Smrg		      offset1+top*srcPitch, offset2+top*srcPitch, width, height,
3664b7e1c893Smrg		      dstPitch*mult/2, xa, xb, ya, &dstBox, src_w, src_h*mult/2,
3665b7e1c893Smrg		      drw_w, drw_h, pPriv->overlay_deinterlacing_method);
3666209ff23fSmrg
3667209ff23fSmrg   RADEONWaitForFifo(pScrn, 1);
3668209ff23fSmrg   OUTREG(RADEON_OV0_REG_LOAD_CNTL,  RADEON_REG_LD_CTL_LOCK);
3669209ff23fSmrg   RADEONWaitForIdleMMIO(pScrn);
3670209ff23fSmrg   while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
3671209ff23fSmrg
3672209ff23fSmrg
3673209ff23fSmrg   switch(pPriv->overlay_deinterlacing_method){
3674209ff23fSmrg        case METHOD_BOB:
3675209ff23fSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
3676209ff23fSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/
3677209ff23fSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
3678209ff23fSmrg           break;
3679209ff23fSmrg        case METHOD_SINGLE:
3680209ff23fSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
3681209ff23fSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
3682209ff23fSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
3683209ff23fSmrg           break;
3684209ff23fSmrg        case METHOD_WEAVE:
3685209ff23fSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28));
3686209ff23fSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0  |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
3687209ff23fSmrg                | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN
3688209ff23fSmrg                /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */
3689209ff23fSmrg                /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */
3690209ff23fSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE);
3691209ff23fSmrg           break;
3692209ff23fSmrg        default:
3693209ff23fSmrg           OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
3694209ff23fSmrg           OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
3695209ff23fSmrg                |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
3696209ff23fSmrg        }
3697209ff23fSmrg
3698209ff23fSmrg
3699209ff23fSmrg   RADEONWaitForIdleMMIO(pScrn);
3700209ff23fSmrg   OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
3701209ff23fSmrg   OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
3702209ff23fSmrg
3703209ff23fSmrg   OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
3704209ff23fSmrg
3705209ff23fSmrg#if 0
3706209ff23fSmrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL));
3707209ff23fSmrg/*   OUTREG(RADEON_OV0_FLAG_CNTL, 8); */
3708209ff23fSmrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL));
3709209ff23fSmrg   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS));
3710209ff23fSmrg
3711209ff23fSmrg/*   OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */
3712209ff23fSmrg#endif
3713209ff23fSmrg
3714209ff23fSmrg   pPriv->videoStatus = CLIENT_VIDEO_ON;
3715209ff23fSmrg   pPriv->video_stream_active = TRUE;
3716209ff23fSmrg
3717209ff23fSmrg   info->VideoTimerCallback = RADEONVideoTimerCallback;
3718209ff23fSmrg
3719209ff23fSmrg   return Success;
3720209ff23fSmrg}
3721209ff23fSmrg        /* miscellaneous TV-in helper functions */
3722209ff23fSmrg
3723209ff23fSmrgstatic void RADEON_board_setmisc(RADEONPortPrivPtr pPriv)
3724209ff23fSmrg{
3725209ff23fSmrg    /* Adjust PAL/SECAM constants for FI1216MF tuner */
3726209ff23fSmrg    if((((pPriv->tuner_type & 0xf)==5) ||
3727209ff23fSmrg        ((pPriv->tuner_type & 0xf)==11)||
3728209ff23fSmrg        ((pPriv->tuner_type & 0xf)==14))
3729209ff23fSmrg        && (pPriv->fi1236!=NULL))
3730209ff23fSmrg    {
3731209ff23fSmrg        if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/
3732209ff23fSmrg        {
3733209ff23fSmrg           pPriv->fi1236->parm.band_low = 0xA1;
3734209ff23fSmrg           pPriv->fi1236->parm.band_mid = 0x91;
3735209ff23fSmrg           pPriv->fi1236->parm.band_high = 0x31;
3736209ff23fSmrg        }
3737209ff23fSmrg        if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/
3738209ff23fSmrg        {
3739209ff23fSmrg           pPriv->fi1236->parm.band_low = 0xA3;
3740209ff23fSmrg           pPriv->fi1236->parm.band_mid = 0x93;
3741209ff23fSmrg           pPriv->fi1236->parm.band_high = 0x33;
3742209ff23fSmrg        }
3743209ff23fSmrg    }
3744209ff23fSmrg
3745209ff23fSmrg}
3746209ff23fSmrg
3747209ff23fSmrgstatic void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
3748209ff23fSmrg{
3749209ff23fSmrgint width, height;
3750209ff23fSmrgRADEONWaitForIdleMMIO(pScrn);
3751209ff23fSmrg
3752209ff23fSmrg/* Disable VBI capture for anything but TV tuner */
3753209ff23fSmrgswitch(pPriv->encoding){
3754209ff23fSmrg	case 2:
3755209ff23fSmrg	case 5:
3756209ff23fSmrg	case 8:
3757209ff23fSmrg		pPriv->capture_vbi_data=1;
3758209ff23fSmrg		break;
3759209ff23fSmrg	default:
3760209ff23fSmrg		pPriv->capture_vbi_data=0;
3761209ff23fSmrg	}
3762209ff23fSmrg
3763209ff23fSmrgswitch(pPriv->encoding){
3764209ff23fSmrg        case 1:
3765209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
3766209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
3767209ff23fSmrg                pPriv->v=25;
3768209ff23fSmrg                break;
3769209ff23fSmrg        case 2:
3770209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
3771209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
3772209ff23fSmrg                pPriv->v=25;
3773209ff23fSmrg                break;
3774209ff23fSmrg        case 3:
3775209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
3776209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL);
3777209ff23fSmrg                pPriv->v=25;
3778209ff23fSmrg                break;
3779209ff23fSmrg        case 4:
3780209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE,0);
3781209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
3782209ff23fSmrg                pPriv->v=23;
3783209ff23fSmrg                break;
3784209ff23fSmrg        case 5:
3785209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
3786209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
3787209ff23fSmrg                pPriv->v=23;
3788209ff23fSmrg                break;
3789209ff23fSmrg        case 6:
3790209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
3791209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE);
3792209ff23fSmrg                pPriv->v=23;
3793209ff23fSmrg                break;
3794209ff23fSmrg        case 7:
3795209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE, 0);
3796209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
3797209ff23fSmrg                pPriv->v=25;
3798209ff23fSmrg                break;
3799209ff23fSmrg        case 8:
3800209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0);
3801209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
3802209ff23fSmrg                pPriv->v=25;
3803209ff23fSmrg                break;
3804209ff23fSmrg        case 9:
3805209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0);
3806209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE);
3807209ff23fSmrg                pPriv->v=25;
3808209ff23fSmrg                break;
3809209ff23fSmrg        case 10:
3810209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0);
3811209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
3812209ff23fSmrg                pPriv->v=25;
3813209ff23fSmrg                break;
3814209ff23fSmrg        case 11:
3815209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0);
3816209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
3817209ff23fSmrg                pPriv->v=25;
3818209ff23fSmrg                break;
3819209ff23fSmrg        case 12:
3820209ff23fSmrg                xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0);
3821209ff23fSmrg                xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60);
3822209ff23fSmrg                pPriv->v=25;
3823209ff23fSmrg                break;
3824209ff23fSmrg        default:
3825209ff23fSmrg                pPriv->v=0;
3826209ff23fSmrg                return;
3827209ff23fSmrg        }
3828209ff23fSmrgxf86_RT_SetInterlace(pPriv->theatre, 1);
3829209ff23fSmrgwidth = InputVideoEncodings[pPriv->encoding].width;
3830209ff23fSmrgheight = InputVideoEncodings[pPriv->encoding].height;
3831209ff23fSmrgxf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data);
3832209ff23fSmrg}
3833209ff23fSmrg
3834209ff23fSmrgstatic void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv)
3835209ff23fSmrg{
3836209ff23fSmrgxf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
3837209ff23fSmrgswitch(pPriv->encoding){
3838209ff23fSmrg        case 1:
3839209ff23fSmrg                pPriv->msp3430->standard = MSP3430_PAL;
3840209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
3841209ff23fSmrg                break;
3842209ff23fSmrg        case 2:
3843209ff23fSmrg                pPriv->msp3430->standard = MSP3430_PAL;
3844209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
3845209ff23fSmrg                break;
3846209ff23fSmrg        case 3:
3847209ff23fSmrg                pPriv->msp3430->standard = MSP3430_PAL;
3848209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
3849209ff23fSmrg                break;
3850209ff23fSmrg        case 4:
3851209ff23fSmrg                pPriv->msp3430->standard = MSP3430_NTSC;
3852209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
3853209ff23fSmrg                break;
3854209ff23fSmrg        case 5:
3855209ff23fSmrg                pPriv->msp3430->standard = MSP3430_NTSC;
3856209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
3857209ff23fSmrg                break;
3858209ff23fSmrg        case 6:
3859209ff23fSmrg                pPriv->msp3430->standard = MSP3430_NTSC;
3860209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
3861209ff23fSmrg                break;
3862209ff23fSmrg        case 7:
3863209ff23fSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
3864209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
3865209ff23fSmrg                break;
3866209ff23fSmrg        case 8:
3867209ff23fSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
3868209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
3869209ff23fSmrg                break;
3870209ff23fSmrg        case 9:
3871209ff23fSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
3872209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
3873209ff23fSmrg                break;
3874209ff23fSmrg        case 10:
3875209ff23fSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
3876209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
3877209ff23fSmrg                break;
3878209ff23fSmrg        case 11:
3879209ff23fSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
3880209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
3881209ff23fSmrg                break;
3882209ff23fSmrg        case 12:
3883209ff23fSmrg                pPriv->msp3430->standard = MSP3430_SECAM;
3884209ff23fSmrg                pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
3885209ff23fSmrg                break;
3886209ff23fSmrg        default:
3887209ff23fSmrg                return;
3888209ff23fSmrg        }
3889209ff23fSmrgxf86_InitMSP3430(pPriv->msp3430);
3890209ff23fSmrgxf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
3891209ff23fSmrg}
3892209ff23fSmrg
3893209ff23fSmrgstatic void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv)
3894209ff23fSmrg{
3895209ff23fSmrgTDA9885Ptr t=pPriv->tda9885;
3896209ff23fSmrg
3897209ff23fSmrgswitch(pPriv->encoding){
3898209ff23fSmrg                /* PAL */
3899209ff23fSmrg        case 1:
3900209ff23fSmrg        case 2:
3901209ff23fSmrg        case 3:
3902209ff23fSmrg                t->standard_video_if=2;
3903209ff23fSmrg                t->standard_sound_carrier=1;
3904209ff23fSmrg					 t->modulation=2; /* negative FM */
3905209ff23fSmrg                break;
3906209ff23fSmrg                /* NTSC */
3907209ff23fSmrg        case 4:
3908209ff23fSmrg        case 5:
3909209ff23fSmrg        case 6:
3910209ff23fSmrg                t->standard_video_if=1;
3911209ff23fSmrg                t->standard_sound_carrier=0;
3912209ff23fSmrg					 t->modulation=2; /* negative FM */
3913209ff23fSmrg                break;
3914209ff23fSmrg                /* SECAM */
3915209ff23fSmrg        case 7:
3916209ff23fSmrg        case 8:
3917209ff23fSmrg        case 9:
3918209ff23fSmrg        case 10:
3919209ff23fSmrg        case 11:
3920209ff23fSmrg        case 12:
3921209ff23fSmrg                t->standard_video_if=0;
3922209ff23fSmrg                t->standard_sound_carrier=3;
3923209ff23fSmrg                t->modulation=0; /* positive AM */
3924209ff23fSmrg                break;
3925209ff23fSmrg        default:
3926209ff23fSmrg                return;
3927209ff23fSmrg        }
3928209ff23fSmrgxf86_tda9885_setparameters(pPriv->tda9885);
3929209ff23fSmrgxf86_tda9885_getstatus(pPriv->tda9885);
3930209ff23fSmrgxf86_tda9885_dumpstatus(pPriv->tda9885);
3931209ff23fSmrg}
3932209ff23fSmrg
3933209ff23fSmrgstatic void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv)
3934209ff23fSmrg{
3935209ff23fSmrg/* at the moment this only affect MT2032 */
3936209ff23fSmrgswitch(pPriv->encoding){
3937209ff23fSmrg                /* PAL */
3938209ff23fSmrg        case 1:
3939209ff23fSmrg        case 2:
3940209ff23fSmrg        case 3:
3941209ff23fSmrg		pPriv->fi1236->video_if=38.900;
3942209ff23fSmrg                break;
3943209ff23fSmrg                /* NTSC */
3944209ff23fSmrg        case 4:
3945209ff23fSmrg        case 5:
3946209ff23fSmrg        case 6:
3947209ff23fSmrg		pPriv->fi1236->video_if=45.7812;
3948209ff23fSmrg		pPriv->fi1236->video_if=45.750;
3949209ff23fSmrg		pPriv->fi1236->video_if=45.125;
3950209ff23fSmrg                break;
3951209ff23fSmrg                /* SECAM */
3952209ff23fSmrg        case 7:
3953209ff23fSmrg        case 8:
3954209ff23fSmrg        case 9:
3955209ff23fSmrg        case 10:
3956209ff23fSmrg        case 11:
3957209ff23fSmrg        case 12:
3958209ff23fSmrg		pPriv->fi1236->video_if=58.7812;
3959209ff23fSmrg                break;
3960209ff23fSmrg        default:
3961209ff23fSmrg                return;
3962209ff23fSmrg        }
3963209ff23fSmrg}
3964209ff23fSmrg
3965