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