radeon_video.c revision 0974d292
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", 328209ff23fSmrg 2048, 2048, 329209ff23fSmrg {1, 1} 330209ff23fSmrg}; 331209ff23fSmrg 332209ff23fSmrg /* the picture is interlaced - hence the half-heights */ 333209ff23fSmrg 334209ff23fSmrgstatic XF86VideoEncodingRec 335209ff23fSmrgInputVideoEncodings[] = 336209ff23fSmrg{ 337209ff23fSmrg { 0, "XV_IMAGE", 2048,2048,{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; 1518ad43ddacSmrg info->xv_max_width = 2048; 1519ad43ddacSmrg info->xv_max_height = 2048; 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 1648209ff23fSmrgvoid 1649209ff23fSmrgRADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup) 1650209ff23fSmrg{ 1651209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1652209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 1653209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1654209ff23fSmrg 1655b7e1c893Smrg if (pPriv->textured) { 1656b7e1c893Smrg if (cleanup) { 1657b7e1c893Smrg if (pPriv->video_memory != NULL) { 1658b7e1c893Smrg radeon_legacy_free_memory(pScrn, pPriv->video_memory); 1659b7e1c893Smrg pPriv->video_memory = NULL; 1660b7e1c893Smrg } 1661b7e1c893Smrg } 1662b7e1c893Smrg return; 1663b7e1c893Smrg } 1664209ff23fSmrg 1665209ff23fSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1666209ff23fSmrg 1667209ff23fSmrg if(cleanup) { 1668209ff23fSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1669209ff23fSmrg RADEONWaitForFifo(pScrn, 2); 1670209ff23fSmrg OUTREG(RADEON_OV0_SCALE_CNTL, 0); 1671209ff23fSmrg } 1672209ff23fSmrg if(pPriv->video_stream_active){ 1673209ff23fSmrg RADEONWaitForFifo(pScrn, 2); 1674209ff23fSmrg OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); 1675209ff23fSmrg OUTREG(RADEON_CAP0_TRIG_CNTL, 0); 1676209ff23fSmrg RADEONResetVideo(pScrn); 1677209ff23fSmrg pPriv->video_stream_active = FALSE; 1678209ff23fSmrg if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 1679209ff23fSmrg if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE); 1680209ff23fSmrg if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1681209ff23fSmrg } 1682209ff23fSmrg if (pPriv->video_memory != NULL) { 1683b7e1c893Smrg radeon_legacy_free_memory(pScrn, pPriv->video_memory); 1684209ff23fSmrg pPriv->video_memory = NULL; 1685209ff23fSmrg } 1686209ff23fSmrg pPriv->videoStatus = 0; 1687209ff23fSmrg } else { 1688209ff23fSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1689209ff23fSmrg pPriv->videoStatus |= OFF_TIMER; 1690209ff23fSmrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 1691209ff23fSmrg } 1692209ff23fSmrg } 1693209ff23fSmrg} 1694209ff23fSmrg 1695209ff23fSmrgint 1696209ff23fSmrgRADEONSetPortAttribute(ScrnInfoPtr pScrn, 1697209ff23fSmrg Atom attribute, 1698209ff23fSmrg INT32 value, 1699209ff23fSmrg pointer data) 1700209ff23fSmrg{ 1701209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1702209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1703209ff23fSmrg Bool setTransform = FALSE; 1704209ff23fSmrg Bool setAlpha = FALSE; 1705209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 1706209ff23fSmrg 1707209ff23fSmrg RADEON_SYNC(info, pScrn); 1708209ff23fSmrg 1709209ff23fSmrg if(attribute == xvAutopaintColorkey) 1710209ff23fSmrg { 1711209ff23fSmrg pPriv->autopaint_colorkey = ClipValue (value, 0, 1); 1712209ff23fSmrg } 1713209ff23fSmrg else if(attribute == xvSetDefaults) 1714209ff23fSmrg { 1715209ff23fSmrg pPriv->autopaint_colorkey = TRUE; 1716209ff23fSmrg pPriv->brightness = 0; 1717209ff23fSmrg pPriv->saturation = 0; 1718209ff23fSmrg pPriv->contrast = 0; 1719209ff23fSmrg pPriv->hue = 0; 1720209ff23fSmrg pPriv->red_intensity = 0; 1721209ff23fSmrg pPriv->green_intensity = 0; 1722209ff23fSmrg pPriv->blue_intensity = 0; 1723209ff23fSmrg pPriv->gamma = 1000; 1724209ff23fSmrg pPriv->transform_index = 0; 1725209ff23fSmrg pPriv->doubleBuffer = FALSE; 1726209ff23fSmrg pPriv->ov_alpha = 255; 1727209ff23fSmrg pPriv->gr_alpha = 255; 1728209ff23fSmrg pPriv->alpha_mode = 0; 1729209ff23fSmrg 1730209ff23fSmrg /* It is simpler to call itself */ 1731209ff23fSmrg RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data); 1732209ff23fSmrg RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data); 1733209ff23fSmrg RADEONSetPortAttribute(pScrn, xvDecContrast, 0, data); 1734209ff23fSmrg RADEONSetPortAttribute(pScrn, xvDecHue, 0, data); 1735209ff23fSmrg 1736209ff23fSmrg RADEONSetPortAttribute(pScrn, xvVolume, -1000, data); 1737209ff23fSmrg RADEONSetPortAttribute(pScrn, xvMute, 1, data); 1738209ff23fSmrg RADEONSetPortAttribute(pScrn, xvSAP, 0, data); 1739209ff23fSmrg RADEONSetPortAttribute(pScrn, xvDoubleBuffer, 1, data); 1740209ff23fSmrg 1741209ff23fSmrg setTransform = TRUE; 1742209ff23fSmrg setAlpha = TRUE; 1743209ff23fSmrg } 1744209ff23fSmrg else if(attribute == xvBrightness) 1745209ff23fSmrg { 1746209ff23fSmrg pPriv->brightness = ClipValue (value, -1000, 1000); 1747209ff23fSmrg setTransform = TRUE; 1748209ff23fSmrg } 1749209ff23fSmrg else if((attribute == xvSaturation) || (attribute == xvColor)) 1750209ff23fSmrg { 1751209ff23fSmrg pPriv->saturation = ClipValue (value, -1000, 1000); 1752209ff23fSmrg setTransform = TRUE; 1753209ff23fSmrg } 1754209ff23fSmrg else if(attribute == xvContrast) 1755209ff23fSmrg { 1756209ff23fSmrg pPriv->contrast = ClipValue (value, -1000, 1000); 1757209ff23fSmrg setTransform = TRUE; 1758209ff23fSmrg } 1759209ff23fSmrg else if(attribute == xvHue) 1760209ff23fSmrg { 1761209ff23fSmrg pPriv->hue = ClipValue (value, -1000, 1000); 1762209ff23fSmrg setTransform = TRUE; 1763209ff23fSmrg } 1764209ff23fSmrg else if(attribute == xvRedIntensity) 1765209ff23fSmrg { 1766209ff23fSmrg pPriv->red_intensity = ClipValue (value, -1000, 1000); 1767209ff23fSmrg setTransform = TRUE; 1768209ff23fSmrg } 1769209ff23fSmrg else if(attribute == xvGreenIntensity) 1770209ff23fSmrg { 1771209ff23fSmrg pPriv->green_intensity = ClipValue (value, -1000, 1000); 1772209ff23fSmrg setTransform = TRUE; 1773209ff23fSmrg } 1774209ff23fSmrg else if(attribute == xvBlueIntensity) 1775209ff23fSmrg { 1776209ff23fSmrg pPriv->blue_intensity = ClipValue (value, -1000, 1000); 1777209ff23fSmrg setTransform = TRUE; 1778209ff23fSmrg } 1779209ff23fSmrg else if(attribute == xvGamma) 1780209ff23fSmrg { 1781209ff23fSmrg pPriv->gamma = ClipValue (value, 100, 10000); 1782209ff23fSmrg setTransform = TRUE; 1783209ff23fSmrg } 1784209ff23fSmrg else if(attribute == xvColorspace) 1785209ff23fSmrg { 1786209ff23fSmrg pPriv->transform_index = ClipValue (value, 0, 1); 1787209ff23fSmrg setTransform = TRUE; 1788209ff23fSmrg } 1789209ff23fSmrg else if(attribute == xvDoubleBuffer) 1790209ff23fSmrg { 1791209ff23fSmrg pPriv->doubleBuffer = ClipValue (value, 0, 1); 1792209ff23fSmrg } 1793209ff23fSmrg else if(attribute == xvColorKey) 1794209ff23fSmrg { 1795209ff23fSmrg pPriv->colorKey = value; 1796209ff23fSmrg RADEONSetColorKey (pScrn, pPriv->colorKey); 1797209ff23fSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1798209ff23fSmrg } 1799209ff23fSmrg else if(attribute == xvCRTC) 1800209ff23fSmrg { 1801209ff23fSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1802209ff23fSmrg if ((value < -1) || (value > xf86_config->num_crtc)) 1803209ff23fSmrg return BadValue; 1804209ff23fSmrg if (value < 0) 1805209ff23fSmrg pPriv->desired_crtc = NULL; 1806209ff23fSmrg else 1807209ff23fSmrg pPriv->desired_crtc = xf86_config->crtc[value]; 1808209ff23fSmrg } 1809209ff23fSmrg else if(attribute == xvOvAlpha) 1810209ff23fSmrg { 1811209ff23fSmrg pPriv->ov_alpha = ClipValue (value, 0, 255); 1812209ff23fSmrg setAlpha = TRUE; 1813209ff23fSmrg } 1814209ff23fSmrg else if(attribute == xvGrAlpha) 1815209ff23fSmrg { 1816209ff23fSmrg pPriv->gr_alpha = ClipValue (value, 0, 255); 1817209ff23fSmrg setAlpha = TRUE; 1818209ff23fSmrg } 1819209ff23fSmrg else if(attribute == xvAlphaMode) 1820209ff23fSmrg { 1821209ff23fSmrg pPriv->alpha_mode = ClipValue (value, 0, 1); 1822209ff23fSmrg setAlpha = TRUE; 1823209ff23fSmrg } 1824209ff23fSmrg else if(attribute == xvDecBrightness) 1825209ff23fSmrg { 1826209ff23fSmrg pPriv->dec_brightness = value; 1827209ff23fSmrg if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness); 1828209ff23fSmrg } 1829209ff23fSmrg else if((attribute == xvDecSaturation) || (attribute == xvDecColor)) 1830209ff23fSmrg { 1831209ff23fSmrg if(value<-1000)value = -1000; 1832209ff23fSmrg if(value>1000)value = 1000; 1833209ff23fSmrg pPriv->dec_saturation = value; 1834209ff23fSmrg if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value); 1835209ff23fSmrg } 1836209ff23fSmrg else if(attribute == xvDecContrast) 1837209ff23fSmrg { 1838209ff23fSmrg pPriv->dec_contrast = value; 1839209ff23fSmrg if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value); 1840209ff23fSmrg } 1841209ff23fSmrg else if(attribute == xvDecHue) 1842209ff23fSmrg { 1843209ff23fSmrg pPriv->dec_hue = value; 1844209ff23fSmrg if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value); 1845209ff23fSmrg } 1846209ff23fSmrg else if(attribute == xvEncoding) 1847209ff23fSmrg { 1848209ff23fSmrg pPriv->encoding = value; 1849209ff23fSmrg if(pPriv->video_stream_active) 1850209ff23fSmrg { 1851209ff23fSmrg if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv); 1852209ff23fSmrg if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv); 1853209ff23fSmrg if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv); 1854209ff23fSmrg if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv); 1855209ff23fSmrg if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1856209ff23fSmrg /* put more here to actually change it */ 1857209ff23fSmrg } 1858209ff23fSmrg } 1859209ff23fSmrg else if(attribute == xvFrequency) 1860209ff23fSmrg { 1861209ff23fSmrg pPriv->frequency = value; 1862209ff23fSmrg /* mute volume if it was not muted before */ 1863209ff23fSmrg if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 1864209ff23fSmrg if((pPriv->uda1380!=NULL)&& !pPriv->mute)xf86_uda1380_mute(pPriv->uda1380, TRUE); 1865209ff23fSmrg if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value); 1866209ff23fSmrg/* if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv); */ 1867209ff23fSmrg if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck)) 1868209ff23fSmrg xf86_InitMSP3430(pPriv->msp3430); 1869209ff23fSmrg if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume)); 1870209ff23fSmrg if((pPriv->uda1380 != NULL)&& !pPriv->mute) xf86_uda1380_setvolume(pPriv->uda1380, pPriv->volume); 1871209ff23fSmrg } 1872209ff23fSmrg else if(attribute == xvMute) 1873209ff23fSmrg { 1874209ff23fSmrg pPriv->mute = value; 1875209ff23fSmrg if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume)); 1876209ff23fSmrg if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1877209ff23fSmrg if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, pPriv->mute); 1878209ff23fSmrg } 1879209ff23fSmrg else if(attribute == xvSAP) 1880209ff23fSmrg { 1881209ff23fSmrg pPriv->sap_channel = value; 1882209ff23fSmrg if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3); 1883209ff23fSmrg } 1884209ff23fSmrg else if(attribute == xvVolume) 1885209ff23fSmrg { 1886209ff23fSmrg if(value<-1000)value = -1000; 1887209ff23fSmrg if(value>1000)value = 1000; 1888209ff23fSmrg pPriv->volume = value; 1889209ff23fSmrg pPriv->mute = FALSE; 1890209ff23fSmrg if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value)); 1891209ff23fSmrg if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1892209ff23fSmrg if(pPriv->uda1380 != NULL) xf86_uda1380_setvolume(pPriv->uda1380, value); 1893209ff23fSmrg } 1894209ff23fSmrg else if(attribute == xvOverlayDeinterlacingMethod) 1895209ff23fSmrg { 1896209ff23fSmrg if(value<0)value = 0; 1897209ff23fSmrg if(value>2)value = 2; 1898209ff23fSmrg pPriv->overlay_deinterlacing_method = value; 1899209ff23fSmrg switch(pPriv->overlay_deinterlacing_method){ 1900209ff23fSmrg case METHOD_BOB: 1901209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 1902209ff23fSmrg break; 1903209ff23fSmrg case METHOD_SINGLE: 1904209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28)); 1905209ff23fSmrg break; 1906209ff23fSmrg case METHOD_WEAVE: 1907209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0); 1908209ff23fSmrg break; 1909209ff23fSmrg default: 1910209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 1911209ff23fSmrg } 1912209ff23fSmrg } 1913209ff23fSmrg else if(attribute == xvDumpStatus) 1914209ff23fSmrg { 1915209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n", 1916209ff23fSmrg pScrn->currentMode->Flags, 1917209ff23fSmrg pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" , 1918209ff23fSmrg pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : "" 1919209ff23fSmrg ); 1920209ff23fSmrg if(pPriv->tda9885 != NULL){ 1921209ff23fSmrg xf86_tda9885_getstatus(pPriv->tda9885); 1922209ff23fSmrg xf86_tda9885_dumpstatus(pPriv->tda9885); 1923209ff23fSmrg } 1924209ff23fSmrg if(pPriv->fi1236!=NULL){ 1925209ff23fSmrg xf86_fi1236_dump_status(pPriv->fi1236); 1926209ff23fSmrg } 1927b7e1c893Smrg } 1928209ff23fSmrg else if(attribute == xvAdjustment) 1929209ff23fSmrg { 1930209ff23fSmrg pPriv->adjustment=value; 1931209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n", 1932209ff23fSmrg (unsigned)pPriv->adjustment); 1933209ff23fSmrg if(pPriv->tda9885!=0){ 1934209ff23fSmrg pPriv->tda9885->top_adjustment=value; 1935209ff23fSmrg RADEON_TDA9885_SetEncoding(pPriv); 1936209ff23fSmrg } 1937209ff23fSmrg } 1938209ff23fSmrg else 1939209ff23fSmrg return BadMatch; 1940209ff23fSmrg 1941209ff23fSmrg if (setTransform) 1942209ff23fSmrg { 1943209ff23fSmrg RADEONSetTransform(pScrn, 1944209ff23fSmrg RTFBrightness(pPriv->brightness), 1945209ff23fSmrg RTFContrast(pPriv->contrast), 1946209ff23fSmrg RTFSaturation(pPriv->saturation), 1947209ff23fSmrg RTFHue(pPriv->hue), 1948209ff23fSmrg RTFIntensity(pPriv->red_intensity), 1949209ff23fSmrg RTFIntensity(pPriv->green_intensity), 1950209ff23fSmrg RTFIntensity(pPriv->blue_intensity), 1951209ff23fSmrg pPriv->transform_index, 1952209ff23fSmrg pPriv->gamma); 1953209ff23fSmrg } 1954209ff23fSmrg 1955209ff23fSmrg if (setAlpha) 1956209ff23fSmrg { 1957209ff23fSmrg RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode); 1958209ff23fSmrg } 1959209ff23fSmrg 1960209ff23fSmrg return Success; 1961209ff23fSmrg} 1962209ff23fSmrg 1963209ff23fSmrgint 1964209ff23fSmrgRADEONGetPortAttribute(ScrnInfoPtr pScrn, 1965209ff23fSmrg Atom attribute, 1966209ff23fSmrg INT32 *value, 1967209ff23fSmrg pointer data) 1968209ff23fSmrg{ 1969209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1970209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1971209ff23fSmrg 1972209ff23fSmrg if (info->accelOn) RADEON_SYNC(info, pScrn); 1973209ff23fSmrg 1974209ff23fSmrg if(attribute == xvAutopaintColorkey) 1975209ff23fSmrg *value = pPriv->autopaint_colorkey; 1976209ff23fSmrg else if(attribute == xvBrightness) 1977209ff23fSmrg *value = pPriv->brightness; 1978209ff23fSmrg else if((attribute == xvSaturation) || (attribute == xvColor)) 1979209ff23fSmrg *value = pPriv->saturation; 1980209ff23fSmrg else if(attribute == xvContrast) 1981209ff23fSmrg *value = pPriv->contrast; 1982209ff23fSmrg else if(attribute == xvHue) 1983209ff23fSmrg *value = pPriv->hue; 1984209ff23fSmrg else if(attribute == xvRedIntensity) 1985209ff23fSmrg *value = pPriv->red_intensity; 1986209ff23fSmrg else if(attribute == xvGreenIntensity) 1987209ff23fSmrg *value = pPriv->green_intensity; 1988209ff23fSmrg else if(attribute == xvBlueIntensity) 1989209ff23fSmrg *value = pPriv->blue_intensity; 1990209ff23fSmrg else if(attribute == xvGamma) 1991209ff23fSmrg *value = pPriv->gamma; 1992209ff23fSmrg else if(attribute == xvColorspace) 1993209ff23fSmrg *value = pPriv->transform_index; 1994209ff23fSmrg else if(attribute == xvDoubleBuffer) 1995209ff23fSmrg *value = pPriv->doubleBuffer ? 1 : 0; 1996209ff23fSmrg else if(attribute == xvColorKey) 1997209ff23fSmrg *value = pPriv->colorKey; 1998209ff23fSmrg else if(attribute == xvCRTC) { 1999209ff23fSmrg int c; 2000209ff23fSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2001209ff23fSmrg for (c = 0; c < xf86_config->num_crtc; c++) 2002209ff23fSmrg if (xf86_config->crtc[c] == pPriv->desired_crtc) 2003209ff23fSmrg break; 2004209ff23fSmrg if (c == xf86_config->num_crtc) 2005209ff23fSmrg c = -1; 2006209ff23fSmrg *value = c; 2007209ff23fSmrg } 2008209ff23fSmrg else if(attribute == xvOvAlpha) 2009209ff23fSmrg *value = pPriv->ov_alpha; 2010209ff23fSmrg else if(attribute == xvGrAlpha) 2011209ff23fSmrg *value = pPriv->gr_alpha; 2012209ff23fSmrg else if(attribute == xvAlphaMode) 2013209ff23fSmrg *value = pPriv->alpha_mode; 2014209ff23fSmrg else if(attribute == xvDecBrightness) 2015209ff23fSmrg *value = pPriv->dec_brightness; 2016209ff23fSmrg else if((attribute == xvDecSaturation) || (attribute == xvDecColor)) 2017209ff23fSmrg *value = pPriv->dec_saturation; 2018209ff23fSmrg else if(attribute == xvDecContrast) 2019209ff23fSmrg *value = pPriv->dec_contrast; 2020209ff23fSmrg else if(attribute == xvDecHue) 2021209ff23fSmrg *value = pPriv->dec_hue; 2022209ff23fSmrg else if(attribute == xvEncoding) 2023209ff23fSmrg *value = pPriv->encoding; 2024209ff23fSmrg else if(attribute == xvFrequency) 2025209ff23fSmrg *value = pPriv->frequency; 2026209ff23fSmrg else 2027209ff23fSmrg if(attribute == xvTunerStatus) { 2028209ff23fSmrg if(pPriv->fi1236==NULL){ 2029209ff23fSmrg *value=TUNER_OFF; 2030209ff23fSmrg } else 2031209ff23fSmrg { 2032209ff23fSmrg *value = xf86_TUNER_get_afc_hint(pPriv->fi1236); 2033209ff23fSmrg } 2034209ff23fSmrg } 2035209ff23fSmrg else if(attribute == xvMute) 2036209ff23fSmrg *value = pPriv->mute; 2037209ff23fSmrg else if(attribute == xvSAP) 2038209ff23fSmrg *value = pPriv->sap_channel; 2039209ff23fSmrg else if(attribute == xvVolume) 2040209ff23fSmrg *value = pPriv->volume; 2041209ff23fSmrg else if(attribute == xvOverlayDeinterlacingMethod) 2042209ff23fSmrg *value = pPriv->overlay_deinterlacing_method; 2043209ff23fSmrg else if(attribute == xvDeviceID) 2044209ff23fSmrg *value = pPriv->device_id; 2045209ff23fSmrg else if(attribute == xvLocationID) 2046209ff23fSmrg *value = pPriv->location_id; 2047209ff23fSmrg else if(attribute == xvInstanceID) 2048209ff23fSmrg *value = pPriv->instance_id; 2049209ff23fSmrg else if(attribute == xvAdjustment) 2050209ff23fSmrg *value = pPriv->adjustment; 2051209ff23fSmrg else 2052209ff23fSmrg return BadMatch; 2053209ff23fSmrg 2054209ff23fSmrg return Success; 2055209ff23fSmrg} 2056209ff23fSmrg 2057209ff23fSmrgvoid 2058209ff23fSmrgRADEONQueryBestSize( 2059209ff23fSmrg ScrnInfoPtr pScrn, 2060209ff23fSmrg Bool motion, 2061209ff23fSmrg short vid_w, short vid_h, 2062209ff23fSmrg short drw_w, short drw_h, 2063209ff23fSmrg unsigned int *p_w, unsigned int *p_h, 2064209ff23fSmrg pointer data 2065209ff23fSmrg){ 2066209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 2067209ff23fSmrg 2068209ff23fSmrg if (!pPriv->textured) { 2069209ff23fSmrg if (vid_w > (drw_w << 4)) 2070209ff23fSmrg drw_w = vid_w >> 4; 2071209ff23fSmrg if (vid_h > (drw_h << 4)) 2072209ff23fSmrg drw_h = vid_h >> 4; 2073209ff23fSmrg } 2074209ff23fSmrg 2075209ff23fSmrg *p_w = drw_w; 2076209ff23fSmrg *p_h = drw_h; 2077209ff23fSmrg} 2078209ff23fSmrg 2079209ff23fSmrgstatic struct { 2080209ff23fSmrg double range; 2081209ff23fSmrg signed char coeff[5][4]; 2082209ff23fSmrg } TapCoeffs[]= 2083209ff23fSmrg { 2084209ff23fSmrg {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2085209ff23fSmrg {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2086209ff23fSmrg {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2087209ff23fSmrg {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2088209ff23fSmrg {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2089209ff23fSmrg {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2090209ff23fSmrg {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2091209ff23fSmrg {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2092209ff23fSmrg {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2093209ff23fSmrg {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2094209ff23fSmrg {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2095209ff23fSmrg {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2096209ff23fSmrg {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2097209ff23fSmrg {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2098209ff23fSmrg {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2099209ff23fSmrg {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2100209ff23fSmrg {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2101209ff23fSmrg {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2102209ff23fSmrg {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2103209ff23fSmrg {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2104209ff23fSmrg {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2105209ff23fSmrg {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2106209ff23fSmrg {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2107209ff23fSmrg {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2108209ff23fSmrg {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2109209ff23fSmrg {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2110209ff23fSmrg {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }}, 2111209ff23fSmrg {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2112209ff23fSmrg {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2113209ff23fSmrg {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2114209ff23fSmrg {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }}, 2115209ff23fSmrg {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2116209ff23fSmrg {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2117209ff23fSmrg {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2118209ff23fSmrg {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2119209ff23fSmrg {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2120209ff23fSmrg {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2121209ff23fSmrg {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2122209ff23fSmrg {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2123209ff23fSmrg {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2124209ff23fSmrg {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2125209ff23fSmrg {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2126209ff23fSmrg {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2127209ff23fSmrg {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2128209ff23fSmrg {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2129209ff23fSmrg {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2130209ff23fSmrg {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2131209ff23fSmrg {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2132209ff23fSmrg {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2133209ff23fSmrg {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2134209ff23fSmrg {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2135209ff23fSmrg {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2136209ff23fSmrg {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, 2137209ff23fSmrg {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, 2138209ff23fSmrg {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2139209ff23fSmrg {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2140209ff23fSmrg {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2141209ff23fSmrg {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }}, 2142209ff23fSmrg {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2143209ff23fSmrg {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2144209ff23fSmrg {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2145209ff23fSmrg {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2146209ff23fSmrg {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2147209ff23fSmrg {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2148209ff23fSmrg {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2149209ff23fSmrg {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2150209ff23fSmrg {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2151209ff23fSmrg {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2152209ff23fSmrg {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2153209ff23fSmrg {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2154209ff23fSmrg {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2155209ff23fSmrg {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2156209ff23fSmrg {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2157209ff23fSmrg {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2158209ff23fSmrg {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}, 2159209ff23fSmrg {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }} 2160209ff23fSmrg }; 2161209ff23fSmrg 2162209ff23fSmrgvoid 2163209ff23fSmrgRADEONCopyData( 2164209ff23fSmrg ScrnInfoPtr pScrn, 2165209ff23fSmrg unsigned char *src, 2166209ff23fSmrg unsigned char *dst, 2167209ff23fSmrg unsigned int srcPitch, 2168209ff23fSmrg unsigned int dstPitch, 2169209ff23fSmrg unsigned int h, 2170209ff23fSmrg unsigned int w, 2171209ff23fSmrg unsigned int bpp 2172209ff23fSmrg){ 2173209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2174209ff23fSmrg 2175209ff23fSmrg /* Get the byte-swapping right for big endian systems */ 2176209ff23fSmrg if ( bpp == 2 ) { 2177209ff23fSmrg w *= 2; 2178209ff23fSmrg bpp = 1; 2179209ff23fSmrg } 2180209ff23fSmrg 2181209ff23fSmrg#ifdef XF86DRI 2182209ff23fSmrg 2183209ff23fSmrg if ( info->directRenderingEnabled && info->DMAForXv ) 2184209ff23fSmrg { 2185209ff23fSmrg uint8_t *buf; 2186209ff23fSmrg uint32_t bufPitch, dstPitchOff; 2187209ff23fSmrg int x, y; 2188209ff23fSmrg unsigned int hpass; 2189209ff23fSmrg 2190209ff23fSmrg RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y ); 2191209ff23fSmrg 2192209ff23fSmrg while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch, 2193209ff23fSmrg x, &y, &h, &hpass )) ) 2194209ff23fSmrg { 2195209ff23fSmrg RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch, 2196209ff23fSmrg srcPitch ); 2197209ff23fSmrg src += hpass * srcPitch; 2198209ff23fSmrg } 2199209ff23fSmrg 2200209ff23fSmrg FLUSH_RING(); 2201209ff23fSmrg 2202209ff23fSmrg return; 2203209ff23fSmrg } 2204209ff23fSmrg else 2205209ff23fSmrg#endif /* XF86DRI */ 2206209ff23fSmrg { 2207ad43ddacSmrg int swap = RADEON_HOST_DATA_SWAP_NONE; 2208ad43ddacSmrg 2209209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 2210ad43ddacSmrg if (info->kms_enabled) { 2211ad43ddacSmrg switch(bpp) { 2212ad43ddacSmrg case 2: 2213ad43ddacSmrg swap = RADEON_HOST_DATA_SWAP_16BIT; 2214ad43ddacSmrg break; 2215ad43ddacSmrg case 4: 2216ad43ddacSmrg swap = RADEON_HOST_DATA_SWAP_32BIT; 2217ad43ddacSmrg break; 2218ad43ddacSmrg } 22190974d292Smrg } else { 22200974d292Smrg switch (pScrn->bitsPerPixel) { 22210974d292Smrg case 16: 22220974d292Smrg swap = RADEON_HOST_DATA_SWAP_16BIT; 22230974d292Smrg break; 22240974d292Smrg case 32: 2225ad43ddacSmrg swap = RADEON_HOST_DATA_SWAP_32BIT; 22260974d292Smrg break; 22270974d292Smrg } 2228209ff23fSmrg } 2229209ff23fSmrg#endif 2230ad43ddacSmrg 2231209ff23fSmrg w *= bpp; 2232209ff23fSmrg 2233ad43ddacSmrg if (dstPitch == w && dstPitch == srcPitch) 2234ad43ddacSmrg RADEONCopySwap(dst, src, h * dstPitch, swap); 2235ad43ddacSmrg else { 2236ad43ddacSmrg while (h--) { 2237ad43ddacSmrg RADEONCopySwap(dst, src, w, swap); 2238ad43ddacSmrg src += srcPitch; 2239ad43ddacSmrg dst += dstPitch; 2240ad43ddacSmrg } 2241209ff23fSmrg } 2242209ff23fSmrg } 2243209ff23fSmrg} 2244209ff23fSmrg 2245209ff23fSmrgstatic void 2246209ff23fSmrgRADEONCopyRGB24Data( 2247209ff23fSmrg ScrnInfoPtr pScrn, 2248209ff23fSmrg unsigned char *src, 2249209ff23fSmrg unsigned char *dst, 2250209ff23fSmrg unsigned int srcPitch, 2251209ff23fSmrg unsigned int dstPitch, 2252209ff23fSmrg unsigned int h, 2253209ff23fSmrg unsigned int w 2254209ff23fSmrg){ 2255209ff23fSmrg uint32_t *dptr; 2256209ff23fSmrg uint8_t *sptr; 2257209ff23fSmrg int i,j; 2258209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2259209ff23fSmrg#ifdef XF86DRI 2260209ff23fSmrg 2261209ff23fSmrg if ( info->directRenderingEnabled && info->DMAForXv ) 2262209ff23fSmrg { 2263209ff23fSmrg uint32_t bufPitch, dstPitchOff; 2264209ff23fSmrg int x, y; 2265209ff23fSmrg unsigned int hpass; 2266209ff23fSmrg 2267209ff23fSmrg RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y ); 2268209ff23fSmrg 2269209ff23fSmrg while ( (dptr = ( uint32_t* )RADEONHostDataBlit( pScrn, 4, w, dstPitchOff, 2270209ff23fSmrg &bufPitch, x, &y, &h, 2271209ff23fSmrg &hpass )) ) 2272209ff23fSmrg { 2273209ff23fSmrg for( j = 0; j < hpass; j++ ) 2274209ff23fSmrg { 2275209ff23fSmrg sptr = src; 2276209ff23fSmrg 2277209ff23fSmrg for ( i = 0 ; i < w; i++, sptr += 3 ) 2278209ff23fSmrg { 2279209ff23fSmrg dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0]; 2280209ff23fSmrg } 2281209ff23fSmrg 2282209ff23fSmrg src += srcPitch; 2283209ff23fSmrg dptr += bufPitch / 4; 2284209ff23fSmrg } 2285209ff23fSmrg } 2286209ff23fSmrg 2287209ff23fSmrg FLUSH_RING(); 2288209ff23fSmrg 2289209ff23fSmrg return; 2290209ff23fSmrg } 2291209ff23fSmrg else 2292209ff23fSmrg#endif /* XF86DRI */ 2293209ff23fSmrg { 2294209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 2295209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 2296ad43ddacSmrg 2297ad43ddacSmrg if (!info->kms_enabled) 2298ad43ddacSmrg OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl & 2299ad43ddacSmrg ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP)); 2300209ff23fSmrg#endif 2301209ff23fSmrg 2302209ff23fSmrg for (j = 0; j < h; j++) { 2303209ff23fSmrg dptr = (uint32_t *)(dst + j * dstPitch); 2304209ff23fSmrg sptr = src + j * srcPitch; 2305209ff23fSmrg 2306209ff23fSmrg for (i = 0; i < w; i++, sptr += 3) { 2307ad43ddacSmrg dptr[i] = cpu_to_le32((sptr[2] << 16) | (sptr[1] << 8) | sptr[0]); 2308209ff23fSmrg } 2309209ff23fSmrg } 2310209ff23fSmrg 2311209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 2312ad43ddacSmrg if (!info->kms_enabled) { 2313ad43ddacSmrg /* restore byte swapping */ 2314ad43ddacSmrg OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl); 2315ad43ddacSmrg } 2316209ff23fSmrg#endif 2317209ff23fSmrg } 2318209ff23fSmrg} 2319209ff23fSmrg 2320209ff23fSmrg 2321209ff23fSmrg#ifdef XF86DRI 2322209ff23fSmrgstatic void RADEON_420_422( 2323209ff23fSmrg unsigned int *d, 2324209ff23fSmrg unsigned char *s1, 2325209ff23fSmrg unsigned char *s2, 2326209ff23fSmrg unsigned char *s3, 2327209ff23fSmrg unsigned int n 2328209ff23fSmrg) 2329209ff23fSmrg{ 2330209ff23fSmrg while ( n ) { 2331209ff23fSmrg *(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); 2332209ff23fSmrg s1+=2; s2++; s3++; 2333209ff23fSmrg n--; 2334209ff23fSmrg } 2335209ff23fSmrg} 2336209ff23fSmrg#endif 2337209ff23fSmrg 2338209ff23fSmrgvoid 2339209ff23fSmrgRADEONCopyMungedData( 2340209ff23fSmrg ScrnInfoPtr pScrn, 2341209ff23fSmrg unsigned char *src1, 2342209ff23fSmrg unsigned char *src2, 2343209ff23fSmrg unsigned char *src3, 2344209ff23fSmrg unsigned char *dst1, 2345209ff23fSmrg unsigned int srcPitch, 2346209ff23fSmrg unsigned int srcPitch2, 2347209ff23fSmrg unsigned int dstPitch, 2348209ff23fSmrg unsigned int h, 2349209ff23fSmrg unsigned int w 2350209ff23fSmrg){ 2351209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2352209ff23fSmrg#ifdef XF86DRI 2353209ff23fSmrg 2354209ff23fSmrg if ( info->directRenderingEnabled && info->DMAForXv ) 2355209ff23fSmrg { 2356209ff23fSmrg uint8_t *buf; 2357209ff23fSmrg uint32_t y = 0, bufPitch, dstPitchOff; 2358209ff23fSmrg int blitX, blitY; 2359209ff23fSmrg unsigned int hpass; 2360209ff23fSmrg 2361209ff23fSmrg /* XXX Fix endian flip on R300 */ 2362209ff23fSmrg 2363209ff23fSmrg RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY ); 2364209ff23fSmrg 2365209ff23fSmrg while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch, 2366209ff23fSmrg blitX, &blitY, &h, &hpass )) ) 2367209ff23fSmrg { 2368209ff23fSmrg while ( hpass-- ) 2369209ff23fSmrg { 2370209ff23fSmrg RADEON_420_422( (unsigned int *) buf, src1, src2, src3, 2371209ff23fSmrg bufPitch / 4 ); 2372209ff23fSmrg src1 += srcPitch; 2373209ff23fSmrg if ( y & 1 ) 2374209ff23fSmrg { 2375209ff23fSmrg src2 += srcPitch2; 2376209ff23fSmrg src3 += srcPitch2; 2377209ff23fSmrg } 2378209ff23fSmrg buf += bufPitch; 2379209ff23fSmrg y++; 2380209ff23fSmrg } 2381209ff23fSmrg } 2382209ff23fSmrg 2383209ff23fSmrg FLUSH_RING(); 2384209ff23fSmrg } 2385209ff23fSmrg else 2386209ff23fSmrg#endif /* XF86DRI */ 2387209ff23fSmrg { 2388209ff23fSmrg uint32_t *dst; 2389209ff23fSmrg uint8_t *s1, *s2, *s3; 2390209ff23fSmrg int i, j; 2391209ff23fSmrg 2392209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 2393209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 2394ad43ddacSmrg 2395ad43ddacSmrg if (!info->kms_enabled) 2396ad43ddacSmrg OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl & 2397ad43ddacSmrg ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP)); 2398209ff23fSmrg#endif 2399209ff23fSmrg 2400209ff23fSmrg w /= 2; 2401209ff23fSmrg 2402209ff23fSmrg for( j = 0; j < h; j++ ) 2403209ff23fSmrg { 2404209ff23fSmrg dst = (pointer)dst1; 2405209ff23fSmrg s1 = src1; s2 = src2; s3 = src3; 2406209ff23fSmrg i = w; 2407209ff23fSmrg while( i > 4 ) 2408209ff23fSmrg { 2409ad43ddacSmrg dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24)); 2410ad43ddacSmrg dst[1] = cpu_to_le32(s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24)); 2411ad43ddacSmrg dst[2] = cpu_to_le32(s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24)); 2412ad43ddacSmrg dst[3] = cpu_to_le32(s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24)); 2413209ff23fSmrg dst += 4; s2 += 4; s3 += 4; s1 += 8; 2414209ff23fSmrg i -= 4; 2415209ff23fSmrg } 2416209ff23fSmrg while( i-- ) 2417209ff23fSmrg { 2418ad43ddacSmrg dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24)); 2419209ff23fSmrg dst++; s2++; s3++; 2420209ff23fSmrg s1 += 2; 2421209ff23fSmrg } 2422209ff23fSmrg 2423209ff23fSmrg dst1 += dstPitch; 2424209ff23fSmrg src1 += srcPitch; 2425209ff23fSmrg if( j & 1 ) 2426209ff23fSmrg { 2427209ff23fSmrg src2 += srcPitch2; 2428209ff23fSmrg src3 += srcPitch2; 2429209ff23fSmrg } 2430209ff23fSmrg } 2431209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 2432ad43ddacSmrg if (!info->kms_enabled) { 2433ad43ddacSmrg /* restore byte swapping */ 2434ad43ddacSmrg OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl); 2435ad43ddacSmrg } 2436209ff23fSmrg#endif 2437209ff23fSmrg } 2438209ff23fSmrg} 2439209ff23fSmrg 2440209ff23fSmrgstatic void 2441209ff23fSmrgRADEONDisplayVideo( 2442209ff23fSmrg ScrnInfoPtr pScrn, 2443209ff23fSmrg xf86CrtcPtr crtc, 2444209ff23fSmrg RADEONPortPrivPtr pPriv, 2445209ff23fSmrg int id, 2446b7e1c893Smrg int base_offset, 2447209ff23fSmrg int offset1, int offset2, 2448209ff23fSmrg int offset3, int offset4, 2449209ff23fSmrg int offset5, int offset6, 2450209ff23fSmrg short width, short height, 2451209ff23fSmrg int pitch, 2452209ff23fSmrg int left, int right, int top, 2453209ff23fSmrg BoxPtr dstBox, 2454209ff23fSmrg short src_w, short src_h, 2455209ff23fSmrg short drw_w, short drw_h, 2456209ff23fSmrg int deinterlacing_method 2457209ff23fSmrg){ 2458209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2459209ff23fSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2460209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 2461209ff23fSmrg uint32_t v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp; 2462209ff23fSmrg double h_inc_d; 2463209ff23fSmrg int p1_h_accum_init, p23_h_accum_init; 2464209ff23fSmrg int p1_v_accum_init, p23_v_accum_init; 2465209ff23fSmrg int p23_blank_lines; 2466209ff23fSmrg int ecp_div; 2467209ff23fSmrg int v_inc_shift; 2468209ff23fSmrg int y_mult; 2469209ff23fSmrg int x_off; 2470209ff23fSmrg int y_off; 2471209ff23fSmrg uint32_t scaler_src; 2472209ff23fSmrg uint32_t dot_clock; 2473209ff23fSmrg int is_rgb; 2474209ff23fSmrg int is_planar; 2475209ff23fSmrg int i; 2476209ff23fSmrg uint32_t scale_cntl; 2477209ff23fSmrg double dsr; 2478209ff23fSmrg int tap_set; 2479209ff23fSmrg int predownscale=0; 2480209ff23fSmrg int src_w_d; 2481209ff23fSmrg int leftuv = 0; 2482209ff23fSmrg DisplayModePtr mode; 2483209ff23fSmrg RADEONOutputPrivatePtr radeon_output; 2484209ff23fSmrg xf86OutputPtr output; 2485209ff23fSmrg RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; 2486209ff23fSmrg 2487209ff23fSmrg is_rgb=0; is_planar=0; 2488209ff23fSmrg switch(id){ 2489209ff23fSmrg case FOURCC_I420: 2490209ff23fSmrg case FOURCC_YV12: 2491209ff23fSmrg is_planar=1; 2492209ff23fSmrg break; 2493209ff23fSmrg case FOURCC_RGBA32: 2494209ff23fSmrg case FOURCC_RGB24: 2495209ff23fSmrg case FOURCC_RGBT16: 2496209ff23fSmrg case FOURCC_RGB16: 2497209ff23fSmrg is_rgb=1; 2498209ff23fSmrg break; 2499209ff23fSmrg default: 2500209ff23fSmrg break; 2501209ff23fSmrg } 2502209ff23fSmrg 2503209ff23fSmrg /* Here we need to find ecp_div again, as the user may have switched resolutions 2504209ff23fSmrg but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to 2505209ff23fSmrg workarounds for chip erratas */ 2506209ff23fSmrg 2507209ff23fSmrg /* Figure out which head we are on for dot clock */ 2508209ff23fSmrg if (radeon_crtc->crtc_id == 1) 2509209ff23fSmrg dot_clock = info->ModeReg->dot_clock_freq_2; 2510209ff23fSmrg else 2511209ff23fSmrg dot_clock = info->ModeReg->dot_clock_freq; 2512209ff23fSmrg 2513209ff23fSmrg if (dot_clock < 17500) 2514209ff23fSmrg ecp_div = 0; 2515209ff23fSmrg else 2516209ff23fSmrg ecp_div = 1; 2517209ff23fSmrg 2518209ff23fSmrg if (ecp_div != info->ecp_div) { 2519209ff23fSmrg info->ecp_div = ecp_div; 2520209ff23fSmrg OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, 2521209ff23fSmrg (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8)); 2522209ff23fSmrg } 2523209ff23fSmrg 2524209ff23fSmrg /* I suspect we may need a usleep after writing to the PLL. if you play a video too soon 2525209ff23fSmrg after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey 2526209ff23fSmrg on the right edge video output. 2527209ff23fSmrg Is this still the case? Might have been chips which need the errata, 2528209ff23fSmrg there is now plenty of usleep after INPLL/OUTPLL for those...*/ 2529209ff23fSmrg 2530209ff23fSmrg v_inc_shift = 20; 2531209ff23fSmrg y_mult = 1; 2532209ff23fSmrg 2533209ff23fSmrg mode = &crtc->mode; 2534209ff23fSmrg 2535209ff23fSmrg if (mode->Flags & V_INTERLACE) 2536209ff23fSmrg v_inc_shift++; 2537209ff23fSmrg if (mode->Flags & V_DBLSCAN) { 2538209ff23fSmrg v_inc_shift--; 2539209ff23fSmrg y_mult = 2; 2540209ff23fSmrg } 2541209ff23fSmrg 2542209ff23fSmrg v_inc = (src_h << v_inc_shift) / drw_h; 2543209ff23fSmrg 2544209ff23fSmrg for (i = 0; i < xf86_config->num_output; i++) { 2545209ff23fSmrg output = xf86_config->output[i]; 2546209ff23fSmrg if (output->crtc == crtc) { 2547209ff23fSmrg radeon_output = output->driver_private; 2548209ff23fSmrg if (radeon_output->Flags & RADEON_USE_RMX) 2549209ff23fSmrg v_inc = ((src_h * mode->CrtcVDisplay / 2550b7e1c893Smrg radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h; 2551209ff23fSmrg break; 2552209ff23fSmrg } 2553209ff23fSmrg } 2554209ff23fSmrg 2555209ff23fSmrg h_inc = (1 << (12 + ecp_div)); 2556209ff23fSmrg 2557209ff23fSmrg step_by_y = 1; 2558209ff23fSmrg step_by_uv = step_by_y; 2559209ff23fSmrg 2560209ff23fSmrg src_w_d = src_w; 2561209ff23fSmrg#if 0 2562209ff23fSmrg /* XXX this does not appear to work */ 2563209ff23fSmrg /* if the source width was larger than what would fit in overlay scaler increase step_by values */ 2564209ff23fSmrg i=src_w; 2565209ff23fSmrg while(i>info->overlay_scaler_buffer_width){ 2566209ff23fSmrg step_by_y++; 2567209ff23fSmrg step_by_uv++; 2568209ff23fSmrg h_inc >>=1; 2569209ff23fSmrg i=i/2; 2570209ff23fSmrg } 2571209ff23fSmrg#else 2572209ff23fSmrg /* predownscale instead (yes this hurts quality) - will only work for widths up 2573209ff23fSmrg to 2 times the overlay_scaler_buffer_width, should be enough */ 2574209ff23fSmrg if (src_w_d > info->overlay_scaler_buffer_width) { 2575209ff23fSmrg src_w_d /= 2; /* odd widths? */ 2576209ff23fSmrg predownscale = 1; 2577209ff23fSmrg } 2578209ff23fSmrg#endif 2579209ff23fSmrg 2580209ff23fSmrg h_inc_d = src_w_d; 2581209ff23fSmrg h_inc_d = h_inc_d/drw_w; 2582209ff23fSmrg /* we could do a tad better - but why 2583209ff23fSmrg bother when this concerns downscaling and the code is so much more 2584209ff23fSmrg hairy */ 2585209ff23fSmrg while(h_inc*h_inc_d >= (2 << 12)) { 2586209ff23fSmrg if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){ 2587209ff23fSmrg step_by_uv = step_by_y+1; 2588209ff23fSmrg break; 2589209ff23fSmrg } 2590209ff23fSmrg step_by_y++; 2591209ff23fSmrg step_by_uv = step_by_y; 2592209ff23fSmrg h_inc >>= 1; 2593209ff23fSmrg } 2594209ff23fSmrg 2595209ff23fSmrg h_inc_uv = h_inc>>(step_by_uv-step_by_y); 2596209ff23fSmrg h_inc = h_inc * h_inc_d; 2597209ff23fSmrg h_inc_uv = h_inc_uv * h_inc_d; 2598209ff23fSmrg /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit 2599209ff23fSmrg in the buffer for 2 tap filtering */ 2600209ff23fSmrg /* the only place it is documented in is in ATI source code */ 2601209ff23fSmrg /* we need twice as much space for 4 tap filtering.. */ 2602209ff23fSmrg /* under special circumstances turn on 4 tap filtering */ 2603209ff23fSmrg /* disable this code for now as it has a DISASTROUS effect on image quality when upscaling 2604209ff23fSmrg at least on rv250 (only as long as the drw_w*2 <=... requirement is still met of course) */ 2605209ff23fSmrg#if 0 2606209ff23fSmrg if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12)) 2607209ff23fSmrg && (deinterlacing_method!=METHOD_WEAVE) 2608209ff23fSmrg && (drw_w*2 <= info->overlay_scaler_buffer_width)){ 2609209ff23fSmrg step_by_y=0; 2610209ff23fSmrg step_by_uv=1; 2611209ff23fSmrg h_inc_uv = h_inc; 2612209ff23fSmrg } 2613209ff23fSmrg#endif 2614209ff23fSmrg 2615b7e1c893Smrg /* Make the overlay base address as close to the buffers as possible to 2616b7e1c893Smrg * prevent the buffer offsets from exceeding the hardware limit of 128 MB. 2617b7e1c893Smrg * The base address must be aligned to a multiple of 4 MB. 2618b7e1c893Smrg */ 2619b7e1c893Smrg base_offset = ((info->fbLocation + base_offset) & (~0 << 22)) - 2620b7e1c893Smrg info->fbLocation; 2621b7e1c893Smrg 2622b7e1c893Smrg offset1 -= base_offset; 2623b7e1c893Smrg offset2 -= base_offset; 2624b7e1c893Smrg offset3 -= base_offset; 2625b7e1c893Smrg offset4 -= base_offset; 2626b7e1c893Smrg offset5 -= base_offset; 2627b7e1c893Smrg offset6 -= base_offset; 2628b7e1c893Smrg 2629209ff23fSmrg /* keep everything in 16.16 */ 2630209ff23fSmrg 2631209ff23fSmrg if (is_planar) { 2632209ff23fSmrg offset1 += ((left >> 16) & ~15); 2633209ff23fSmrg offset2 += ((left >> 16) & ~31) >> 1; 2634209ff23fSmrg offset3 += ((left >> 16) & ~31) >> 1; 2635209ff23fSmrg offset4 += ((left >> 16) & ~15); 2636209ff23fSmrg offset5 += ((left >> 16) & ~31) >> 1; 2637209ff23fSmrg offset6 += ((left >> 16) & ~31) >> 1; 2638209ff23fSmrg offset2 |= RADEON_VIF_BUF0_PITCH_SEL; 2639209ff23fSmrg offset3 |= RADEON_VIF_BUF0_PITCH_SEL; 2640209ff23fSmrg offset5 |= RADEON_VIF_BUF0_PITCH_SEL; 2641209ff23fSmrg offset6 |= RADEON_VIF_BUF0_PITCH_SEL; 2642209ff23fSmrg } 2643209ff23fSmrg else { 2644209ff23fSmrg /* is this really correct for non-2-byte formats? */ 2645209ff23fSmrg offset1 += ((left >> 16) & ~7) << 1; 2646209ff23fSmrg offset2 += ((left >> 16) & ~7) << 1; 2647209ff23fSmrg offset3 += ((left >> 16) & ~7) << 1; 2648209ff23fSmrg offset4 += ((left >> 16) & ~7) << 1; 2649209ff23fSmrg offset5 += ((left >> 16) & ~7) << 1; 2650209ff23fSmrg offset6 += ((left >> 16) & ~7) << 1; 2651209ff23fSmrg } 2652209ff23fSmrg 2653209ff23fSmrg tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); 2654209ff23fSmrg p1_h_accum_init = ((tmp << 4) & 0x000f8000) | 2655209ff23fSmrg ((tmp << 12) & 0xf0000000); 2656209ff23fSmrg 2657209ff23fSmrg tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2); 2658209ff23fSmrg p23_h_accum_init = ((tmp << 4) & 0x000f8000) | 2659209ff23fSmrg ((tmp << 12) & 0x70000000); 2660209ff23fSmrg 2661209ff23fSmrg tmp = (top & 0x0000ffff) + 0x00018000; 2662209ff23fSmrg p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 2663209ff23fSmrg (((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01); 2664209ff23fSmrg 2665209ff23fSmrg if (is_planar) { 2666209ff23fSmrg p23_v_accum_init = ((tmp << 4) & 0x03ff8000) | 2667209ff23fSmrg ((deinterlacing_method != METHOD_WEAVE) ? 0x03 : 0x01); 2668209ff23fSmrg p23_blank_lines = (((src_h >> 1) - 1) << 16); 2669209ff23fSmrg } 2670209ff23fSmrg else { 2671209ff23fSmrg p23_v_accum_init = 0; 2672209ff23fSmrg p23_blank_lines = 0; 2673209ff23fSmrg } 2674209ff23fSmrg 2675209ff23fSmrg if (is_planar) { 2676209ff23fSmrg leftuv = ((left >> 16) >> 1) & 15; 2677209ff23fSmrg left = (left >> 16) & 15; 2678209ff23fSmrg } 2679209ff23fSmrg else { 2680209ff23fSmrg left = (left >> 16) & 7; 2681209ff23fSmrg if (!is_rgb) 2682209ff23fSmrg leftuv = left >> 1; 2683209ff23fSmrg } 2684209ff23fSmrg 2685209ff23fSmrg RADEONWaitForFifo(pScrn, 2); 2686209ff23fSmrg OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK); 2687209ff23fSmrg if (info->accelOn) RADEON_SYNC(info, pScrn); 2688209ff23fSmrg while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK)); 2689209ff23fSmrg 2690209ff23fSmrg RADEONWaitForFifo(pScrn, 10); 2691209ff23fSmrg OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16)); 2692209ff23fSmrg OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) | 2693209ff23fSmrg predownscale << 4 | predownscale << 12); 2694209ff23fSmrg 2695209ff23fSmrg x_off = 8; 2696209ff23fSmrg y_off = 0; 2697209ff23fSmrg 2698209ff23fSmrg if (IS_R300_VARIANT || 2699209ff23fSmrg (info->ChipFamily == CHIP_FAMILY_R200)) 2700209ff23fSmrg x_off = 0; 2701209ff23fSmrg 2702209ff23fSmrg /* needed to make the overlay work on crtc1 in leftof and above modes */ 2703209ff23fSmrg /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */ 2704209ff23fSmrg /* 2705209ff23fSmrg if (srel == radeonLeftOf) { 2706209ff23fSmrg x_off -= mode->CrtcHDisplay; 2707209ff23fSmrg } 2708209ff23fSmrg if (srel == radeonAbove) { 2709209ff23fSmrg y_off -= mode->CrtcVDisplay; 2710209ff23fSmrg } 2711209ff23fSmrg */ 2712209ff23fSmrg 2713209ff23fSmrg /* Put the hardware overlay on CRTC2: 2714209ff23fSmrg * 2715209ff23fSmrg * Since one hardware overlay can not be displayed on two heads 2716209ff23fSmrg * at the same time, we might need to consider using software 2717209ff23fSmrg * rendering for the second head. 2718209ff23fSmrg */ 2719209ff23fSmrg 2720209ff23fSmrg if (radeon_crtc->crtc_id == 1) { 2721209ff23fSmrg x_off = 0; 2722209ff23fSmrg OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) | 2723209ff23fSmrg ((dstBox->y1*y_mult) << 16))); 2724209ff23fSmrg OUTREG(RADEON_OV1_Y_X_END, ((dstBox->x2 + x_off) | 2725209ff23fSmrg ((dstBox->y2*y_mult) << 16))); 2726209ff23fSmrg scaler_src = RADEON_SCALER_CRTC_SEL; 2727209ff23fSmrg } else { 2728209ff23fSmrg OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) | 2729209ff23fSmrg (((dstBox->y1*y_mult) + y_off) << 16))); 2730209ff23fSmrg OUTREG(RADEON_OV0_Y_X_END, ((dstBox->x2 + x_off) | 2731209ff23fSmrg (((dstBox->y2*y_mult) + y_off) << 16))); 2732209ff23fSmrg scaler_src = 0; 2733209ff23fSmrg } 2734209ff23fSmrg 2735209ff23fSmrg /* program the tap coefficients for better downscaling quality. 2736209ff23fSmrg Could do slightly better by using hardcoded coefficients for one axis 2737209ff23fSmrg in case only the other axis is downscaled (see RADEON_OV0_FILTER_CNTL) */ 2738209ff23fSmrg dsr=(double)(1<<0xC)/h_inc; 2739209ff23fSmrg if(dsr<0.25)dsr=0.25; 2740209ff23fSmrg if(dsr>1.0)dsr=1.0; 2741209ff23fSmrg tap_set=(int)((dsr-0.25)*100); 2742209ff23fSmrg for(i=0;i<5;i++){ 2743209ff23fSmrg OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) | 2744209ff23fSmrg ((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) | 2745209ff23fSmrg ((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) | 2746209ff23fSmrg ((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24)); 2747209ff23fSmrg } 2748209ff23fSmrg 2749209ff23fSmrg RADEONWaitForFifo(pScrn, 11); 2750209ff23fSmrg OUTREG(RADEON_OV0_V_INC, v_inc); 2751209ff23fSmrg OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16)); 2752209ff23fSmrg OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | p23_blank_lines); 2753209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch); 2754209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch); 2755209ff23fSmrg OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16)); 2756209ff23fSmrg if (!is_rgb) 2757209ff23fSmrg src_w >>= 1; 2758209ff23fSmrg OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16)); 2759209ff23fSmrg OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16)); 2760b7e1c893Smrg if (info->ModeReg->ov0_base_addr != (info->fbLocation + base_offset)) { 2761b7e1c893Smrg ErrorF("Changing OV0_BASE_ADDR from 0x%08x to 0x%08x\n", 2762b7e1c893Smrg info->ModeReg->ov0_base_addr, info->fbLocation + base_offset); 2763b7e1c893Smrg info->ModeReg->ov0_base_addr = info->fbLocation + base_offset; 2764b7e1c893Smrg OUTREG(RADEON_OV0_BASE_ADDR, info->ModeReg->ov0_base_addr); 2765b7e1c893Smrg } 2766209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1); 2767209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2); 2768209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3); 2769209ff23fSmrg 2770209ff23fSmrg RADEONWaitForFifo(pScrn, 9); 2771209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4); 2772209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset5); 2773209ff23fSmrg OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset6); 2774209ff23fSmrg OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init); 2775209ff23fSmrg OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init); 2776209ff23fSmrg OUTREG(RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init); 2777209ff23fSmrg OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init); 2778209ff23fSmrg 2779209ff23fSmrg scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER 2780209ff23fSmrg | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16) | scaler_src; 2781209ff23fSmrg switch(id){ 2782209ff23fSmrg case FOURCC_UYVY: 2783209ff23fSmrg scale_cntl |= RADEON_SCALER_SOURCE_YVYU422; 2784209ff23fSmrg break; 2785209ff23fSmrg case FOURCC_RGB24: 2786209ff23fSmrg case FOURCC_RGBA32: 2787209ff23fSmrg scale_cntl |= RADEON_SCALER_SOURCE_32BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2788209ff23fSmrg break; 2789209ff23fSmrg case FOURCC_RGB16: 2790209ff23fSmrg scale_cntl |= RADEON_SCALER_SOURCE_16BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2791209ff23fSmrg break; 2792209ff23fSmrg case FOURCC_RGBT16: 2793209ff23fSmrg scale_cntl |= RADEON_SCALER_SOURCE_15BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2794209ff23fSmrg break; 2795209ff23fSmrg case FOURCC_YV12: 2796209ff23fSmrg case FOURCC_I420: 2797209ff23fSmrg scale_cntl |= RADEON_SCALER_SOURCE_YUV12; 2798209ff23fSmrg break; 2799209ff23fSmrg case FOURCC_YUY2: 2800209ff23fSmrg default: 2801209ff23fSmrg scale_cntl |= RADEON_SCALER_SOURCE_VYUY422 2802209ff23fSmrg | ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0); 2803209ff23fSmrg break; 2804209ff23fSmrg } 2805209ff23fSmrg 2806209ff23fSmrg if (info->ChipFamily < CHIP_FAMILY_R200) { 2807209ff23fSmrg scale_cntl &= ~RADEON_SCALER_GAMMA_SEL_MASK; 2808209ff23fSmrg scale_cntl |= ((RADEONTranslateUserGamma(pPriv->gamma)) << 5); 2809209ff23fSmrg } 2810209ff23fSmrg 2811209ff23fSmrg OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl); 2812209ff23fSmrg OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0); 2813209ff23fSmrg} 2814209ff23fSmrg 2815209ff23fSmrg 2816209ff23fSmrgstatic void 2817209ff23fSmrgRADEONFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes) 2818209ff23fSmrg{ 2819209ff23fSmrg#if HAVE_XV_DRAWABLE_HELPER 2820209ff23fSmrg xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes); 2821209ff23fSmrg#else 2822209ff23fSmrg xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes); 2823209ff23fSmrg#endif 2824209ff23fSmrg} 2825209ff23fSmrg 2826209ff23fSmrg 2827209ff23fSmrgstatic int 2828209ff23fSmrgRADEONPutImage( 2829209ff23fSmrg ScrnInfoPtr pScrn, 2830209ff23fSmrg short src_x, short src_y, 2831209ff23fSmrg short drw_x, short drw_y, 2832209ff23fSmrg short src_w, short src_h, 2833209ff23fSmrg short drw_w, short drw_h, 2834209ff23fSmrg int id, unsigned char* buf, 2835209ff23fSmrg short width, short height, 2836209ff23fSmrg Bool Sync, 2837209ff23fSmrg RegionPtr clipBoxes, pointer data, 2838209ff23fSmrg DrawablePtr pDraw 2839209ff23fSmrg){ 2840209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2841209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 2842209ff23fSmrg INT32 xa, xb, ya, yb; 2843209ff23fSmrg unsigned char *dst_start; 2844209ff23fSmrg int new_size, offset, s2offset, s3offset; 2845209ff23fSmrg int srcPitch, srcPitch2, dstPitch; 2846209ff23fSmrg int d2line, d3line; 2847209ff23fSmrg int top, left, npixels, nlines, bpp; 2848209ff23fSmrg int idconv = id; 2849209ff23fSmrg BoxRec dstBox; 2850209ff23fSmrg uint32_t tmp; 2851209ff23fSmrg xf86CrtcPtr crtc; 2852209ff23fSmrg 2853209ff23fSmrg /* 2854209ff23fSmrg * s2offset, s3offset - byte offsets into U and V plane of the 2855209ff23fSmrg * source where copying starts. Y plane is 2856209ff23fSmrg * done by editing "buf". 2857209ff23fSmrg * 2858209ff23fSmrg * offset - byte offset to the first line of the destination. 2859209ff23fSmrg * 2860209ff23fSmrg * dst_start - byte address to the first displayed pel. 2861209ff23fSmrg * 2862209ff23fSmrg */ 2863209ff23fSmrg 2864209ff23fSmrg /* make the compiler happy */ 2865209ff23fSmrg s2offset = s3offset = srcPitch2 = 0; 2866209ff23fSmrg d2line = d3line = 0; 2867209ff23fSmrg 2868209ff23fSmrg if(src_w > (drw_w << 4)) 2869209ff23fSmrg drw_w = src_w >> 4; 2870209ff23fSmrg if(src_h > (drw_h << 4)) 2871209ff23fSmrg drw_h = src_h >> 4; 2872209ff23fSmrg 2873209ff23fSmrg /* Clip */ 2874209ff23fSmrg xa = src_x; 2875209ff23fSmrg xb = src_x + src_w; 2876209ff23fSmrg ya = src_y; 2877209ff23fSmrg yb = src_y + src_h; 2878209ff23fSmrg 2879209ff23fSmrg dstBox.x1 = drw_x; 2880209ff23fSmrg dstBox.x2 = drw_x + drw_w; 2881209ff23fSmrg dstBox.y1 = drw_y; 2882209ff23fSmrg dstBox.y2 = drw_y + drw_h; 2883209ff23fSmrg 2884209ff23fSmrg if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc, 2885209ff23fSmrg &dstBox, &xa, &xb, &ya, &yb, 2886209ff23fSmrg clipBoxes, width, height)) 2887209ff23fSmrg return Success; 2888209ff23fSmrg 2889209ff23fSmrg if (!crtc) { 2890209ff23fSmrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 2891209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 2892209ff23fSmrg OUTREG(RADEON_OV0_SCALE_CNTL, 0); 2893209ff23fSmrg pPriv->videoStatus &= ~CLIENT_VIDEO_ON; 2894209ff23fSmrg } 2895209ff23fSmrg return Success; 2896209ff23fSmrg } 2897209ff23fSmrg 2898209ff23fSmrg dstBox.x1 -= crtc->x; 2899209ff23fSmrg dstBox.x2 -= crtc->x; 2900209ff23fSmrg dstBox.y1 -= crtc->y; 2901209ff23fSmrg dstBox.y2 -= crtc->y; 2902209ff23fSmrg 2903209ff23fSmrg bpp = pScrn->bitsPerPixel >> 3; 2904209ff23fSmrg 2905209ff23fSmrg switch(id) { 2906209ff23fSmrg case FOURCC_RGB24: 2907209ff23fSmrg dstPitch = width * 4; 2908209ff23fSmrg srcPitch = width * 3; 2909209ff23fSmrg break; 2910209ff23fSmrg case FOURCC_RGBA32: 2911209ff23fSmrg dstPitch = width * 4; 2912209ff23fSmrg srcPitch = width * 4; 2913209ff23fSmrg break; 2914209ff23fSmrg case FOURCC_RGB16: 2915209ff23fSmrg case FOURCC_RGBT16: 2916209ff23fSmrg dstPitch = width * 2; 2917ad43ddacSmrg srcPitch = RADEON_ALIGN(width * 2, 4); 2918209ff23fSmrg break; 2919209ff23fSmrg case FOURCC_YV12: 2920209ff23fSmrg case FOURCC_I420: 2921209ff23fSmrg /* it seems rs4xx chips (all of them???) either can't handle planar 2922209ff23fSmrg yuv at all or would need some unknown different setup. */ 2923209ff23fSmrg if ((info->ChipFamily != CHIP_FAMILY_RS400) && 2924209ff23fSmrg (info->ChipFamily != CHIP_FAMILY_RS480)) { 2925209ff23fSmrg /* need 16bytes alignment for u,v plane, so 2 times that for width 2926209ff23fSmrg but blitter needs 64bytes alignment. 128byte is a waste but dstpitch 2927209ff23fSmrg for uv planes needs to be dstpitch yplane >> 1 for now. */ 2928ad43ddacSmrg dstPitch = (RADEON_ALIGN(width, 128)); 2929ad43ddacSmrg srcPitch = RADEON_ALIGN(width, 4); 2930209ff23fSmrg } 2931209ff23fSmrg else { 2932209ff23fSmrg dstPitch = width * 2; 2933ad43ddacSmrg srcPitch = RADEON_ALIGN(width, 4); 2934209ff23fSmrg idconv = FOURCC_YUY2; 2935209ff23fSmrg } 2936209ff23fSmrg break; 2937209ff23fSmrg case FOURCC_UYVY: 2938209ff23fSmrg case FOURCC_YUY2: 2939209ff23fSmrg default: 2940209ff23fSmrg dstPitch = width * 2; 2941209ff23fSmrg srcPitch = width * 2; 2942209ff23fSmrg break; 2943209ff23fSmrg } 2944209ff23fSmrg 2945209ff23fSmrg#ifdef XF86DRI 2946209ff23fSmrg if (info->directRenderingEnabled && info->DMAForXv) { 2947209ff23fSmrg /* The upload blit only supports multiples of 64 bytes */ 2948ad43ddacSmrg dstPitch = RADEON_ALIGN(dstPitch, 64); 2949209ff23fSmrg } else 2950209ff23fSmrg#endif 2951209ff23fSmrg /* The overlay only supports multiples of 16 bytes */ 2952ad43ddacSmrg dstPitch = RADEON_ALIGN(dstPitch, 16); 2953209ff23fSmrg 2954209ff23fSmrg new_size = dstPitch * height; 2955209ff23fSmrg if (idconv == FOURCC_YV12 || id == FOURCC_I420) { 2956ad43ddacSmrg new_size += (dstPitch >> 1) * (RADEON_ALIGN(height, 2)); 2957209ff23fSmrg } 2958b7e1c893Smrg pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory, 2959b7e1c893Smrg (pPriv->doubleBuffer ? 2960ad43ddacSmrg (new_size * 2) : new_size), 64, 2961ad43ddacSmrg RADEON_GEM_DOMAIN_VRAM); 2962209ff23fSmrg if (pPriv->video_offset == 0) 2963209ff23fSmrg return BadAlloc; 2964209ff23fSmrg 2965209ff23fSmrg pPriv->currentBuffer ^= 1; 2966209ff23fSmrg 2967209ff23fSmrg /* copy data */ 2968209ff23fSmrg top = ya >> 16; 2969209ff23fSmrg left = (xa >> 16) & ~1; 2970ad43ddacSmrg npixels = (RADEON_ALIGN((xb + 0xffff) >> 16, 2)) - left; 2971209ff23fSmrg 2972209ff23fSmrg offset = (pPriv->video_offset) + (top * dstPitch); 2973209ff23fSmrg 2974209ff23fSmrg if(pPriv->doubleBuffer) { 2975209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 2976209ff23fSmrg 2977209ff23fSmrg /* Wait for last flip to take effect */ 2978209ff23fSmrg while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK)); 2979209ff23fSmrg 2980209ff23fSmrg offset += pPriv->currentBuffer * new_size; 2981209ff23fSmrg } 2982209ff23fSmrg 2983209ff23fSmrg dst_start = info->FB + offset; 2984209ff23fSmrg 2985209ff23fSmrg switch(id) { 2986209ff23fSmrg case FOURCC_YV12: 2987209ff23fSmrg case FOURCC_I420: 2988209ff23fSmrg if (id == idconv) { 2989209ff23fSmrg /* meh. Such a mess just for someone who wants to watch half the video clipped */ 2990209ff23fSmrg top &= ~1; 2991209ff23fSmrg /* odd number of pixels? That may not work correctly */ 2992ad43ddacSmrg srcPitch2 = RADEON_ALIGN(width >> 1, 4); 2993209ff23fSmrg /* odd number of lines? Maybe... */ 2994ad43ddacSmrg s2offset = srcPitch * (RADEON_ALIGN(height, 2)); 2995209ff23fSmrg s3offset = s2offset + srcPitch2 * ((height + 1) >> 1); 2996209ff23fSmrg s2offset += (top >> 1) * srcPitch2 + (left >> 1); 2997209ff23fSmrg s3offset += (top >> 1) * srcPitch2 + (left >> 1); 2998209ff23fSmrg d2line = (height * dstPitch); 2999209ff23fSmrg d3line = d2line + ((height + 1) >> 1) * (dstPitch >> 1); 3000209ff23fSmrg nlines = ((yb + 0xffff) >> 16) - top; 3001209ff23fSmrg d2line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch); 3002209ff23fSmrg d3line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch); 3003209ff23fSmrg if(id == FOURCC_YV12) { 3004209ff23fSmrg tmp = s2offset; 3005209ff23fSmrg s2offset = s3offset; 3006209ff23fSmrg s3offset = tmp; 3007209ff23fSmrg } 3008209ff23fSmrg RADEONCopyData(pScrn, buf + (top * srcPitch) + left, dst_start + left, 3009209ff23fSmrg srcPitch, dstPitch, nlines, npixels, 1); 3010209ff23fSmrg RADEONCopyData(pScrn, buf + s2offset, dst_start + d2line + (left >> 1), 3011209ff23fSmrg srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1); 3012209ff23fSmrg RADEONCopyData(pScrn, buf + s3offset, dst_start + d3line + (left >> 1), 3013209ff23fSmrg srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1); 3014209ff23fSmrg } 3015209ff23fSmrg else { 3016209ff23fSmrg s2offset = srcPitch * height; 3017ad43ddacSmrg srcPitch2 = RADEON_ALIGN(width >> 1, 4); 3018209ff23fSmrg s3offset = (srcPitch2 * (height >> 1)) + s2offset; 3019209ff23fSmrg top &= ~1; 3020209ff23fSmrg dst_start += left << 1; 3021209ff23fSmrg tmp = ((top >> 1) * srcPitch2) + (left >> 1); 3022209ff23fSmrg s2offset += tmp; 3023209ff23fSmrg s3offset += tmp; 3024209ff23fSmrg if(id == FOURCC_I420) { 3025209ff23fSmrg tmp = s2offset; 3026209ff23fSmrg s2offset = s3offset; 3027209ff23fSmrg s3offset = tmp; 3028209ff23fSmrg } 3029ad43ddacSmrg nlines = (RADEON_ALIGN((yb + 0xffff) >> 16, 2)) - top; 3030209ff23fSmrg RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left, 3031209ff23fSmrg buf + s2offset, buf + s3offset, dst_start, 3032209ff23fSmrg srcPitch, srcPitch2, dstPitch, nlines, npixels); 3033209ff23fSmrg } 3034209ff23fSmrg break; 3035209ff23fSmrg case FOURCC_RGBT16: 3036209ff23fSmrg case FOURCC_RGB16: 3037209ff23fSmrg case FOURCC_UYVY: 3038209ff23fSmrg case FOURCC_YUY2: 3039209ff23fSmrg default: 3040209ff23fSmrg left <<= 1; 3041209ff23fSmrg buf += (top * srcPitch) + left; 3042209ff23fSmrg nlines = ((yb + 0xffff) >> 16) - top; 3043209ff23fSmrg dst_start += left; 3044209ff23fSmrg RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2); 3045209ff23fSmrg break; 3046209ff23fSmrg case FOURCC_RGBA32: 3047209ff23fSmrg buf += (top * srcPitch) + left*4; 3048209ff23fSmrg nlines = ((yb + 0xffff) >> 16) - top; 3049209ff23fSmrg dst_start += left*4; 3050209ff23fSmrg RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4); 3051209ff23fSmrg break; 3052209ff23fSmrg case FOURCC_RGB24: 3053209ff23fSmrg buf += (top * srcPitch) + left*3; 3054209ff23fSmrg nlines = ((yb + 0xffff) >> 16) - top; 3055209ff23fSmrg dst_start += left*4; 3056209ff23fSmrg RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels); 3057209ff23fSmrg break; 3058209ff23fSmrg } 3059209ff23fSmrg 3060209ff23fSmrg /* update cliplist */ 3061209ff23fSmrg if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) 3062209ff23fSmrg { 3063209ff23fSmrg REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 3064209ff23fSmrg /* draw these */ 3065209ff23fSmrg if(pPriv->autopaint_colorkey) 3066209ff23fSmrg RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 3067209ff23fSmrg } 3068209ff23fSmrg 3069209ff23fSmrg /* FIXME: someone should look at these offsets, I don't think it makes sense how 3070209ff23fSmrg they are handled throughout the source. */ 3071b7e1c893Smrg RADEONDisplayVideo(pScrn, crtc, pPriv, idconv, pPriv->video_offset, offset, 3072b7e1c893Smrg offset + d2line, offset + d3line, offset, offset + d2line, 3073b7e1c893Smrg offset + d3line, width, height, dstPitch, xa, xb, ya, 3074b7e1c893Smrg &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB); 3075209ff23fSmrg 3076209ff23fSmrg pPriv->videoStatus = CLIENT_VIDEO_ON; 3077209ff23fSmrg 3078209ff23fSmrg info->VideoTimerCallback = RADEONVideoTimerCallback; 3079209ff23fSmrg 3080209ff23fSmrg return Success; 3081209ff23fSmrg} 3082209ff23fSmrg 3083209ff23fSmrg 3084209ff23fSmrgint 3085209ff23fSmrgRADEONQueryImageAttributes( 3086209ff23fSmrg ScrnInfoPtr pScrn, 3087209ff23fSmrg int id, 3088209ff23fSmrg unsigned short *w, unsigned short *h, 3089209ff23fSmrg int *pitches, int *offsets 3090209ff23fSmrg){ 3091ad43ddacSmrg const RADEONInfoRec * const info = RADEONPTR(pScrn); 3092209ff23fSmrg int size, tmp; 3093209ff23fSmrg 3094ad43ddacSmrg if(*w > info->xv_max_width) *w = info->xv_max_width; 3095ad43ddacSmrg if(*h > info->xv_max_height) *h = info->xv_max_height; 3096209ff23fSmrg 3097ad43ddacSmrg *w = RADEON_ALIGN(*w, 2); 3098209ff23fSmrg if(offsets) offsets[0] = 0; 3099209ff23fSmrg 3100209ff23fSmrg switch(id) { 3101209ff23fSmrg case FOURCC_YV12: 3102209ff23fSmrg case FOURCC_I420: 3103ad43ddacSmrg *h = RADEON_ALIGN(*h, 2); 3104ad43ddacSmrg size = RADEON_ALIGN(*w, 4); 3105209ff23fSmrg if(pitches) pitches[0] = size; 3106209ff23fSmrg size *= *h; 3107209ff23fSmrg if(offsets) offsets[1] = size; 3108ad43ddacSmrg tmp = RADEON_ALIGN(*w >> 1, 4); 3109209ff23fSmrg if(pitches) pitches[1] = pitches[2] = tmp; 3110209ff23fSmrg tmp *= (*h >> 1); 3111209ff23fSmrg size += tmp; 3112209ff23fSmrg if(offsets) offsets[2] = size; 3113209ff23fSmrg size += tmp; 3114209ff23fSmrg break; 3115209ff23fSmrg case FOURCC_RGBA32: 3116209ff23fSmrg size = *w << 2; 3117209ff23fSmrg if(pitches) pitches[0] = size; 3118209ff23fSmrg size *= *h; 3119209ff23fSmrg break; 3120209ff23fSmrg case FOURCC_RGB24: 3121209ff23fSmrg size = *w * 3; 3122209ff23fSmrg if(pitches) pitches[0] = size; 3123209ff23fSmrg size *= *h; 3124209ff23fSmrg break; 3125209ff23fSmrg case FOURCC_RGBT16: 3126209ff23fSmrg case FOURCC_RGB16: 3127209ff23fSmrg case FOURCC_UYVY: 3128209ff23fSmrg case FOURCC_YUY2: 3129209ff23fSmrg default: 3130209ff23fSmrg size = *w << 1; 3131209ff23fSmrg if(pitches) pitches[0] = size; 3132209ff23fSmrg size *= *h; 3133209ff23fSmrg break; 3134209ff23fSmrg } 3135209ff23fSmrg 3136209ff23fSmrg return size; 3137209ff23fSmrg} 3138209ff23fSmrg 3139209ff23fSmrgstatic void 3140209ff23fSmrgRADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now) 3141209ff23fSmrg{ 3142209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 3143209ff23fSmrg RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; 3144209ff23fSmrg 3145209ff23fSmrg if(pPriv->videoStatus & TIMER_MASK) { 3146209ff23fSmrg if(pPriv->videoStatus & OFF_TIMER) { 3147209ff23fSmrg if(pPriv->offTime < now) { 3148209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 3149209ff23fSmrg OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3150209ff23fSmrg pPriv->videoStatus = FREE_TIMER; 3151209ff23fSmrg pPriv->freeTime = now + FREE_DELAY; 3152209ff23fSmrg } 3153209ff23fSmrg } else { /* FREE_TIMER */ 3154209ff23fSmrg if(pPriv->freeTime < now) { 3155209ff23fSmrg if (pPriv->video_memory != NULL) { 3156b7e1c893Smrg radeon_legacy_free_memory(pScrn, pPriv->video_memory); 3157209ff23fSmrg pPriv->video_memory = NULL; 3158209ff23fSmrg } 3159209ff23fSmrg pPriv->videoStatus = 0; 3160209ff23fSmrg info->VideoTimerCallback = NULL; 3161209ff23fSmrg } 3162209ff23fSmrg } 3163209ff23fSmrg } else /* shouldn't get here */ 3164209ff23fSmrg info->VideoTimerCallback = NULL; 3165209ff23fSmrg} 3166209ff23fSmrg 3167209ff23fSmrg/****************** Offscreen stuff ***************/ 3168209ff23fSmrgtypedef struct { 3169209ff23fSmrg void *surface_memory; 3170209ff23fSmrg Bool isOn; 3171209ff23fSmrg} OffscreenPrivRec, * OffscreenPrivPtr; 3172209ff23fSmrg 3173209ff23fSmrgstatic int 3174209ff23fSmrgRADEONAllocateSurface( 3175209ff23fSmrg ScrnInfoPtr pScrn, 3176209ff23fSmrg int id, 3177209ff23fSmrg unsigned short w, 3178209ff23fSmrg unsigned short h, 3179209ff23fSmrg XF86SurfacePtr surface 3180209ff23fSmrg){ 3181209ff23fSmrg int offset, pitch, size; 3182209ff23fSmrg OffscreenPrivPtr pPriv; 3183209ff23fSmrg void *surface_memory = NULL; 3184209ff23fSmrg if((w > 1024) || (h > 1024)) 3185209ff23fSmrg return BadAlloc; 3186209ff23fSmrg 3187ad43ddacSmrg w = RADEON_ALIGN(w, 2); 3188ad43ddacSmrg pitch = RADEON_ALIGN(w << 1, 16); 3189209ff23fSmrg size = pitch * h; 3190209ff23fSmrg 3191ad43ddacSmrg offset = radeon_legacy_allocate_memory(pScrn, &surface_memory, size, 64, 3192ad43ddacSmrg RADEON_GEM_DOMAIN_VRAM); 3193209ff23fSmrg if (offset == 0) 3194209ff23fSmrg return BadAlloc; 3195209ff23fSmrg 3196209ff23fSmrg surface->width = w; 3197209ff23fSmrg surface->height = h; 3198209ff23fSmrg 31992f39173dSmrg if(!(surface->pitches = malloc(sizeof(int)))) { 3200b7e1c893Smrg radeon_legacy_free_memory(pScrn, surface_memory); 3201209ff23fSmrg return BadAlloc; 3202209ff23fSmrg } 32032f39173dSmrg if(!(surface->offsets = malloc(sizeof(int)))) { 32042f39173dSmrg free(surface->pitches); 3205b7e1c893Smrg radeon_legacy_free_memory(pScrn, surface_memory); 3206209ff23fSmrg return BadAlloc; 3207209ff23fSmrg } 32082f39173dSmrg if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 32092f39173dSmrg free(surface->pitches); 32102f39173dSmrg free(surface->offsets); 3211b7e1c893Smrg radeon_legacy_free_memory(pScrn, surface_memory); 3212209ff23fSmrg return BadAlloc; 3213209ff23fSmrg } 3214209ff23fSmrg 3215209ff23fSmrg pPriv->surface_memory = surface_memory; 3216209ff23fSmrg pPriv->isOn = FALSE; 3217209ff23fSmrg 3218209ff23fSmrg surface->pScrn = pScrn; 3219209ff23fSmrg surface->id = id; 3220209ff23fSmrg surface->pitches[0] = pitch; 3221209ff23fSmrg surface->offsets[0] = offset; 3222209ff23fSmrg surface->devPrivate.ptr = (pointer)pPriv; 3223209ff23fSmrg 3224209ff23fSmrg return Success; 3225209ff23fSmrg} 3226209ff23fSmrg 3227209ff23fSmrgstatic int 3228209ff23fSmrgRADEONStopSurface( 3229209ff23fSmrg XF86SurfacePtr surface 3230209ff23fSmrg){ 3231209ff23fSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3232209ff23fSmrg RADEONInfoPtr info = RADEONPTR(surface->pScrn); 3233209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 3234209ff23fSmrg 3235209ff23fSmrg if(pPriv->isOn) { 3236209ff23fSmrg OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3237209ff23fSmrg pPriv->isOn = FALSE; 3238209ff23fSmrg } 3239209ff23fSmrg return Success; 3240209ff23fSmrg} 3241209ff23fSmrg 3242209ff23fSmrg 3243209ff23fSmrgstatic int 3244209ff23fSmrgRADEONFreeSurface( 3245209ff23fSmrg XF86SurfacePtr surface 3246209ff23fSmrg){ 3247209ff23fSmrg ScrnInfoPtr pScrn = surface->pScrn; 3248209ff23fSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3249209ff23fSmrg 3250209ff23fSmrg if(pPriv->isOn) 3251209ff23fSmrg RADEONStopSurface(surface); 3252b7e1c893Smrg radeon_legacy_free_memory(pScrn, pPriv->surface_memory); 3253b7e1c893Smrg pPriv->surface_memory = NULL; 32542f39173dSmrg free(surface->pitches); 32552f39173dSmrg free(surface->offsets); 32562f39173dSmrg free(surface->devPrivate.ptr); 3257209ff23fSmrg 3258209ff23fSmrg return Success; 3259209ff23fSmrg} 3260209ff23fSmrg 3261209ff23fSmrgstatic int 3262209ff23fSmrgRADEONGetSurfaceAttribute( 3263209ff23fSmrg ScrnInfoPtr pScrn, 3264209ff23fSmrg Atom attribute, 3265209ff23fSmrg INT32 *value 3266209ff23fSmrg){ 3267209ff23fSmrg return RADEONGetPortAttribute(pScrn, attribute, value, 3268209ff23fSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 3269209ff23fSmrg} 3270209ff23fSmrg 3271209ff23fSmrgstatic int 3272209ff23fSmrgRADEONSetSurfaceAttribute( 3273209ff23fSmrg ScrnInfoPtr pScrn, 3274209ff23fSmrg Atom attribute, 3275209ff23fSmrg INT32 value 3276209ff23fSmrg){ 3277209ff23fSmrg return RADEONSetPortAttribute(pScrn, attribute, value, 3278209ff23fSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 3279209ff23fSmrg} 3280209ff23fSmrg 3281209ff23fSmrg 3282209ff23fSmrgstatic int 3283209ff23fSmrgRADEONDisplaySurface( 3284209ff23fSmrg XF86SurfacePtr surface, 3285209ff23fSmrg short src_x, short src_y, 3286209ff23fSmrg short drw_x, short drw_y, 3287209ff23fSmrg short src_w, short src_h, 3288209ff23fSmrg short drw_w, short drw_h, 3289209ff23fSmrg RegionPtr clipBoxes 3290209ff23fSmrg){ 3291209ff23fSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3292209ff23fSmrg ScrnInfoPtr pScrn = surface->pScrn; 3293209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 3294209ff23fSmrg RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr; 3295209ff23fSmrg 3296209ff23fSmrg INT32 xa, ya, xb, yb; 3297209ff23fSmrg BoxRec dstBox; 3298209ff23fSmrg xf86CrtcPtr crtc; 3299209ff23fSmrg 3300209ff23fSmrg if (src_w > (drw_w << 4)) 3301209ff23fSmrg drw_w = src_w >> 4; 3302209ff23fSmrg if (src_h > (drw_h << 4)) 3303209ff23fSmrg drw_h = src_h >> 4; 3304209ff23fSmrg 3305209ff23fSmrg xa = src_x; 3306209ff23fSmrg xb = src_x + src_w; 3307209ff23fSmrg ya = src_y; 3308209ff23fSmrg yb = src_y + src_h; 3309209ff23fSmrg 3310209ff23fSmrg dstBox.x1 = drw_x; 3311209ff23fSmrg dstBox.x2 = drw_x + drw_w; 3312209ff23fSmrg dstBox.y1 = drw_y; 3313209ff23fSmrg dstBox.y2 = drw_y + drw_h; 3314209ff23fSmrg 3315209ff23fSmrg if (!radeon_crtc_clip_video(pScrn, &crtc, portPriv->desired_crtc, 3316209ff23fSmrg &dstBox, &xa, &xb, &ya, &yb, clipBoxes, 3317209ff23fSmrg surface->width, surface->height)) 3318209ff23fSmrg return Success; 3319209ff23fSmrg 3320209ff23fSmrg if (!crtc) { 3321209ff23fSmrg if (pPriv->isOn) { 3322209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 3323209ff23fSmrg OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3324209ff23fSmrg pPriv->isOn = FALSE; 3325209ff23fSmrg } 3326209ff23fSmrg return Success; 3327209ff23fSmrg } 3328209ff23fSmrg 3329209ff23fSmrg dstBox.x1 -= crtc->x; 3330209ff23fSmrg dstBox.x2 -= crtc->x; 3331209ff23fSmrg dstBox.y1 -= crtc->y; 3332209ff23fSmrg dstBox.y2 -= crtc->y; 3333209ff23fSmrg 3334209ff23fSmrg#if 0 3335209ff23fSmrg /* this isn't needed */ 3336209ff23fSmrg RADEONResetVideo(pScrn); 3337209ff23fSmrg#endif 3338209ff23fSmrg RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id, 3339209ff23fSmrg surface->offsets[0], surface->offsets[0], 3340209ff23fSmrg surface->offsets[0], surface->offsets[0], 3341209ff23fSmrg surface->offsets[0], surface->offsets[0], 3342b7e1c893Smrg surface->offsets[0], surface->width, surface->height, 3343b7e1c893Smrg surface->pitches[0], xa, xb, ya, &dstBox, src_w, src_h, 3344b7e1c893Smrg drw_w, drw_h, METHOD_BOB); 3345209ff23fSmrg 3346209ff23fSmrg if (portPriv->autopaint_colorkey) 3347209ff23fSmrg xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 3348209ff23fSmrg 3349209ff23fSmrg pPriv->isOn = TRUE; 3350209ff23fSmrg /* we've prempted the XvImage stream so set its free timer */ 3351209ff23fSmrg if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 3352209ff23fSmrg REGION_EMPTY(pScrn->pScreen, &portPriv->clip); 3353209ff23fSmrg UpdateCurrentTime(); 3354209ff23fSmrg portPriv->videoStatus = FREE_TIMER; 3355209ff23fSmrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 3356209ff23fSmrg info->VideoTimerCallback = RADEONVideoTimerCallback; 3357209ff23fSmrg } 3358209ff23fSmrg 3359209ff23fSmrg return Success; 3360209ff23fSmrg} 3361209ff23fSmrg 3362209ff23fSmrg 3363209ff23fSmrgstatic void 3364209ff23fSmrgRADEONInitOffscreenImages(ScreenPtr pScreen) 3365209ff23fSmrg{ 3366209ff23fSmrg/* ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 3367209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); */ 3368209ff23fSmrg XF86OffscreenImagePtr offscreenImages; 3369209ff23fSmrg /* need to free this someplace */ 3370209ff23fSmrg 33712f39173dSmrg if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 3372209ff23fSmrg return; 3373209ff23fSmrg 3374209ff23fSmrg offscreenImages[0].image = &Images[0]; 3375209ff23fSmrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*| 3376209ff23fSmrg VIDEO_CLIP_TO_VIEWPORT*/; 3377209ff23fSmrg offscreenImages[0].alloc_surface = RADEONAllocateSurface; 3378209ff23fSmrg offscreenImages[0].free_surface = RADEONFreeSurface; 3379209ff23fSmrg offscreenImages[0].display = RADEONDisplaySurface; 3380209ff23fSmrg offscreenImages[0].stop = RADEONStopSurface; 3381209ff23fSmrg offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute; 3382209ff23fSmrg offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute; 3383209ff23fSmrg offscreenImages[0].max_width = 2048; 3384209ff23fSmrg offscreenImages[0].max_height = 2048; 3385209ff23fSmrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 3386209ff23fSmrg offscreenImages[0].attributes = Attributes; 3387209ff23fSmrg 3388209ff23fSmrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 3389209ff23fSmrg} 3390209ff23fSmrg 3391209ff23fSmrg /* TV-in functions */ 3392209ff23fSmrg 3393209ff23fSmrgstatic int 3394209ff23fSmrgRADEONPutVideo( 3395209ff23fSmrg ScrnInfoPtr pScrn, 3396209ff23fSmrg short src_x, short src_y, 3397209ff23fSmrg short drw_x, short drw_y, 3398209ff23fSmrg short src_w, short src_h, 3399209ff23fSmrg short drw_w, short drw_h, 3400209ff23fSmrg RegionPtr clipBoxes, pointer data, 3401209ff23fSmrg DrawablePtr pDraw 3402209ff23fSmrg){ 3403209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 3404209ff23fSmrg RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 3405209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 3406209ff23fSmrg INT32 xa, xb, ya, yb, top; 3407209ff23fSmrg unsigned int pitch, new_size, alloc_size; 3408209ff23fSmrg unsigned int offset1, offset2, offset3, offset4, s2offset, s3offset; 3409209ff23fSmrg unsigned int vbi_offset0, vbi_offset1; 3410209ff23fSmrg int srcPitch, srcPitch2, dstPitch; 3411209ff23fSmrg int bpp; 3412209ff23fSmrg BoxRec dstBox; 3413209ff23fSmrg uint32_t id, display_base; 3414209ff23fSmrg int width, height; 3415209ff23fSmrg int mult; 3416209ff23fSmrg int vbi_line_width, vbi_start, vbi_end; 3417209ff23fSmrg xf86CrtcPtr crtc; 3418209ff23fSmrg 3419209ff23fSmrg RADEON_SYNC(info, pScrn); 3420209ff23fSmrg /* 3421209ff23fSmrg * s2offset, s3offset - byte offsets into U and V plane of the 3422209ff23fSmrg * source where copying starts. Y plane is 3423209ff23fSmrg * done by editing "buf". 3424209ff23fSmrg * 3425209ff23fSmrg * offset - byte offset to the first line of the destination. 3426209ff23fSmrg * 3427209ff23fSmrg * dst_start - byte address to the first displayed pel. 3428209ff23fSmrg * 3429209ff23fSmrg */ 3430209ff23fSmrg 3431209ff23fSmrg /* make the compiler happy */ 3432209ff23fSmrg s2offset = s3offset = srcPitch2 = 0; 3433209ff23fSmrg 3434209ff23fSmrg if(src_w > (drw_w << 4)) 3435209ff23fSmrg drw_w = src_w >> 4; 3436209ff23fSmrg if(src_h > (drw_h << 4)) 3437209ff23fSmrg drw_h = src_h >> 4; 3438209ff23fSmrg 3439209ff23fSmrg /* Clip */ 3440209ff23fSmrg xa = src_x; 3441209ff23fSmrg xb = src_x + src_w; 3442209ff23fSmrg ya = src_y; 3443209ff23fSmrg yb = src_y + src_h; 3444209ff23fSmrg 3445209ff23fSmrg dstBox.x1 = drw_x; 3446209ff23fSmrg dstBox.x2 = drw_x + drw_w; 3447209ff23fSmrg dstBox.y1 = drw_y; 3448209ff23fSmrg dstBox.y2 = drw_y + drw_h; 3449209ff23fSmrg 3450209ff23fSmrg width = InputVideoEncodings[pPriv->encoding].width; 3451209ff23fSmrg height = InputVideoEncodings[pPriv->encoding].height; 3452209ff23fSmrg 3453209ff23fSmrg vbi_line_width = 798*2; 3454209ff23fSmrg if(width<=640) 3455209ff23fSmrg vbi_line_width = 0x640; /* 1600 actually */ 3456209ff23fSmrg else 3457209ff23fSmrg vbi_line_width = 2000; /* might need adjustment */ 3458209ff23fSmrg 3459209ff23fSmrg if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc, 3460209ff23fSmrg &dstBox, &xa, &xb, &ya, &yb, 3461209ff23fSmrg clipBoxes, width, height)) 3462209ff23fSmrg return Success; 3463209ff23fSmrg 3464209ff23fSmrg if (!crtc) { 3465209ff23fSmrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 3466209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 3467209ff23fSmrg OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3468209ff23fSmrg pPriv->videoStatus &= ~CLIENT_VIDEO_ON; 3469209ff23fSmrg } 3470209ff23fSmrg return Success; 3471209ff23fSmrg } 3472209ff23fSmrg 3473209ff23fSmrg dstBox.x1 -= crtc->x; 3474209ff23fSmrg dstBox.x2 -= crtc->x; 3475209ff23fSmrg dstBox.y1 -= crtc->y; 3476209ff23fSmrg dstBox.y2 -= crtc->y; 3477209ff23fSmrg 3478209ff23fSmrg bpp = pScrn->bitsPerPixel >> 3; 3479209ff23fSmrg pitch = bpp * pScrn->displayWidth; 3480209ff23fSmrg 3481209ff23fSmrg switch(pPriv->overlay_deinterlacing_method){ 3482209ff23fSmrg case METHOD_BOB: 3483209ff23fSmrg case METHOD_SINGLE: 3484209ff23fSmrg mult=2; 3485209ff23fSmrg break; 3486209ff23fSmrg case METHOD_WEAVE: 3487209ff23fSmrg case METHOD_ADAPTIVE: 3488209ff23fSmrg mult=4; 3489209ff23fSmrg break; 3490209ff23fSmrg default: 3491209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n"); 3492209ff23fSmrg mult=4; 3493209ff23fSmrg } 3494209ff23fSmrg 3495209ff23fSmrg id = FOURCC_YUY2; 3496209ff23fSmrg 3497209ff23fSmrg top = ya>>16; 3498209ff23fSmrg#if 0 3499209ff23fSmrg /* setting the ID above makes this useful - needs revisiting */ 3500209ff23fSmrg switch(id) { 3501209ff23fSmrg case FOURCC_YV12: 3502209ff23fSmrg case FOURCC_I420: 3503209ff23fSmrg top &= ~1; 3504ad43ddacSmrg dstPitch = RADEON_ALIGN(width << 1, 16); 3505ad43ddacSmrg srcPitch = RADEON_ALIGN(width, 4); 3506209ff23fSmrg s2offset = srcPitch * height; 3507ad43ddacSmrg srcPitch2 = RADEON_ALIGN(width >> 1, 4); 3508209ff23fSmrg s3offset = (srcPitch2 * (height >> 1)) + s2offset; 3509209ff23fSmrg break; 3510209ff23fSmrg case FOURCC_UYVY: 3511209ff23fSmrg case FOURCC_YUY2: 3512209ff23fSmrg default: 3513ad43ddacSmrg dstPitch = RADEON_ALIGN(width<<1, 16); 3514209ff23fSmrg srcPitch = (width<<1); 3515209ff23fSmrg break; 3516209ff23fSmrg } 3517209ff23fSmrg#else 3518ad43ddacSmrg dstPitch = RADEON_ALIGN(width << 1, 16); 3519209ff23fSmrg srcPitch = (width<<1); 3520209ff23fSmrg#endif 3521209ff23fSmrg 3522209ff23fSmrg new_size = dstPitch * height; 3523209ff23fSmrg new_size = new_size + 0x1f; /* for aligning */ 3524209ff23fSmrg alloc_size = new_size * mult; 3525209ff23fSmrg if (pPriv->capture_vbi_data) 3526209ff23fSmrg alloc_size += 2 * 2 * vbi_line_width * 21; 3527209ff23fSmrg 3528b7e1c893Smrg pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory, 3529b7e1c893Smrg (pPriv->doubleBuffer ? 3530ad43ddacSmrg (new_size * 2) : new_size), 64, 3531ad43ddacSmrg RADEON_GEM_DOMAIN_GTT); 3532209ff23fSmrg if (pPriv->video_offset == 0) 3533209ff23fSmrg return BadAlloc; 3534209ff23fSmrg 3535209ff23fSmrg/* I have suspicion that capture engine must be active _before_ Rage Theatre 3536209ff23fSmrg is being manipulated with.. */ 3537209ff23fSmrg 3538209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 3539209ff23fSmrg display_base=INREG(RADEON_DISPLAY_BASE_ADDR); 3540209ff23fSmrg 3541209ff23fSmrg/* RADEONWaitForFifo(pScrn, 15); */ 3542209ff23fSmrg 3543209ff23fSmrg switch(pPriv->overlay_deinterlacing_method){ 3544209ff23fSmrg case METHOD_BOB: 3545209ff23fSmrg case METHOD_SINGLE: 3546ad43ddacSmrg offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10); 3547ad43ddacSmrg offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10); 3548209ff23fSmrg offset3 = offset1; 3549209ff23fSmrg offset4 = offset2; 3550209ff23fSmrg break; 3551209ff23fSmrg case METHOD_WEAVE: 3552ad43ddacSmrg offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10); 3553209ff23fSmrg offset2 = offset1+dstPitch; 3554ad43ddacSmrg offset3 = RADEON_ALIGN(pPriv->video_offset + 2 * new_size, 0x10); 3555209ff23fSmrg offset4 = offset3+dstPitch; 3556209ff23fSmrg break; 3557209ff23fSmrg default: 3558ad43ddacSmrg offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10); 3559ad43ddacSmrg offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10); 3560209ff23fSmrg offset3 = offset1; 3561209ff23fSmrg offset4 = offset2; 3562209ff23fSmrg } 3563209ff23fSmrg 3564209ff23fSmrg OUTREG(RADEON_CAP0_BUF0_OFFSET, offset1+display_base); 3565209ff23fSmrg OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET, offset2+display_base); 3566209ff23fSmrg OUTREG(RADEON_CAP0_BUF1_OFFSET, offset3+display_base); 3567209ff23fSmrg OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET, offset4+display_base); 3568209ff23fSmrg 3569209ff23fSmrg OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base); 3570209ff23fSmrg 3571209ff23fSmrg if(pPriv->capture_vbi_data){ 3572209ff23fSmrg if ((pPriv->encoding==2)||(pPriv->encoding==8)) { 3573209ff23fSmrg /* PAL, SECAM */ 3574209ff23fSmrg vbi_start = 5; 3575209ff23fSmrg vbi_end = 21; 3576209ff23fSmrg } else { 3577209ff23fSmrg /* NTSC */ 3578209ff23fSmrg vbi_start = 8; 3579209ff23fSmrg vbi_end = 20; 3580209ff23fSmrg } 3581209ff23fSmrg 3582ad43ddacSmrg vbi_offset0 = RADEON_ALIGN(pPriv->video_offset + mult * new_size * bpp, 0x10); 3583209ff23fSmrg vbi_offset1 = vbi_offset0 + dstPitch*20; 3584209ff23fSmrg OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base); 3585209ff23fSmrg OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base); 3586209ff23fSmrg OUTREG(RADEON_CAP0_VBI2_OFFSET, 0); 3587209ff23fSmrg OUTREG(RADEON_CAP0_VBI3_OFFSET, 0); 3588209ff23fSmrg OUTREG(RADEON_CAP0_VBI_V_WINDOW, vbi_start | (vbi_end<<16)); 3589209ff23fSmrg OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16); 3590209ff23fSmrg } 3591209ff23fSmrg 3592209ff23fSmrg OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2); 3593209ff23fSmrg OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16); 3594209ff23fSmrg OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1)); 3595209ff23fSmrg if(mult==2){ 3596209ff23fSmrg OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB); 3597209ff23fSmrg } else { 3598209ff23fSmrg OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE); 3599209ff23fSmrg } 3600209ff23fSmrg OUTREG(RADEON_CAP0_DEBUG, 0); 3601209ff23fSmrg 3602209ff23fSmrg OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01); 3603209ff23fSmrg OUTREG(RADEON_TEST_DEBUG_CNTL, 0); 3604209ff23fSmrg 3605209ff23fSmrg if(! pPriv->video_stream_active) 3606209ff23fSmrg { 3607209ff23fSmrg 3608209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 3609209ff23fSmrg OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 ); 3610209ff23fSmrg OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0); 3611209ff23fSmrg OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK); 3612209ff23fSmrg OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11); 3613209ff23fSmrg if(pPriv->theatre != NULL) 3614209ff23fSmrg { 3615209ff23fSmrg RADEON_RT_SetEncoding(pScrn, pPriv); 3616209ff23fSmrg } 3617209ff23fSmrg if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv); 3618209ff23fSmrg if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv); 3619209ff23fSmrg if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv); 3620209ff23fSmrg if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv); 3621209ff23fSmrg } 3622209ff23fSmrg 3623209ff23fSmrg 3624209ff23fSmrg /* update cliplist */ 3625209ff23fSmrg if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 3626209ff23fSmrg REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 3627209ff23fSmrg /* draw these */ 3628209ff23fSmrg if(pPriv->autopaint_colorkey) 3629209ff23fSmrg RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 3630209ff23fSmrg } 3631209ff23fSmrg 3632b7e1c893Smrg RADEONDisplayVideo(pScrn, crtc, pPriv, id, pPriv->video_offset, 3633b7e1c893Smrg offset1+top*srcPitch, offset2+top*srcPitch, 3634b7e1c893Smrg offset3+top*srcPitch, offset4+top*srcPitch, 3635b7e1c893Smrg offset1+top*srcPitch, offset2+top*srcPitch, width, height, 3636b7e1c893Smrg dstPitch*mult/2, xa, xb, ya, &dstBox, src_w, src_h*mult/2, 3637b7e1c893Smrg drw_w, drw_h, pPriv->overlay_deinterlacing_method); 3638209ff23fSmrg 3639209ff23fSmrg RADEONWaitForFifo(pScrn, 1); 3640209ff23fSmrg OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK); 3641209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 3642209ff23fSmrg while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK)); 3643209ff23fSmrg 3644209ff23fSmrg 3645209ff23fSmrg switch(pPriv->overlay_deinterlacing_method){ 3646209ff23fSmrg case METHOD_BOB: 3647209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 3648209ff23fSmrg OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/ 3649209ff23fSmrg |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3650209ff23fSmrg break; 3651209ff23fSmrg case METHOD_SINGLE: 3652209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28)); 3653209ff23fSmrg OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3654209ff23fSmrg |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3655209ff23fSmrg break; 3656209ff23fSmrg case METHOD_WEAVE: 3657209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28)); 3658209ff23fSmrg OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0 |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3659209ff23fSmrg | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 3660209ff23fSmrg /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */ 3661209ff23fSmrg /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */ 3662209ff23fSmrg |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE); 3663209ff23fSmrg break; 3664209ff23fSmrg default: 3665209ff23fSmrg OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 3666209ff23fSmrg OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3667209ff23fSmrg |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3668209ff23fSmrg } 3669209ff23fSmrg 3670209ff23fSmrg 3671209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 3672209ff23fSmrg OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE )); 3673209ff23fSmrg OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE )); 3674209ff23fSmrg 3675209ff23fSmrg OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0); 3676209ff23fSmrg 3677209ff23fSmrg#if 0 3678209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL)); 3679209ff23fSmrg/* OUTREG(RADEON_OV0_FLAG_CNTL, 8); */ 3680209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL)); 3681209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS)); 3682209ff23fSmrg 3683209ff23fSmrg/* OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */ 3684209ff23fSmrg#endif 3685209ff23fSmrg 3686209ff23fSmrg pPriv->videoStatus = CLIENT_VIDEO_ON; 3687209ff23fSmrg pPriv->video_stream_active = TRUE; 3688209ff23fSmrg 3689209ff23fSmrg info->VideoTimerCallback = RADEONVideoTimerCallback; 3690209ff23fSmrg 3691209ff23fSmrg return Success; 3692209ff23fSmrg} 3693209ff23fSmrg /* miscellaneous TV-in helper functions */ 3694209ff23fSmrg 3695209ff23fSmrgstatic void RADEON_board_setmisc(RADEONPortPrivPtr pPriv) 3696209ff23fSmrg{ 3697209ff23fSmrg /* Adjust PAL/SECAM constants for FI1216MF tuner */ 3698209ff23fSmrg if((((pPriv->tuner_type & 0xf)==5) || 3699209ff23fSmrg ((pPriv->tuner_type & 0xf)==11)|| 3700209ff23fSmrg ((pPriv->tuner_type & 0xf)==14)) 3701209ff23fSmrg && (pPriv->fi1236!=NULL)) 3702209ff23fSmrg { 3703209ff23fSmrg if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/ 3704209ff23fSmrg { 3705209ff23fSmrg pPriv->fi1236->parm.band_low = 0xA1; 3706209ff23fSmrg pPriv->fi1236->parm.band_mid = 0x91; 3707209ff23fSmrg pPriv->fi1236->parm.band_high = 0x31; 3708209ff23fSmrg } 3709209ff23fSmrg if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/ 3710209ff23fSmrg { 3711209ff23fSmrg pPriv->fi1236->parm.band_low = 0xA3; 3712209ff23fSmrg pPriv->fi1236->parm.band_mid = 0x93; 3713209ff23fSmrg pPriv->fi1236->parm.band_high = 0x33; 3714209ff23fSmrg } 3715209ff23fSmrg } 3716209ff23fSmrg 3717209ff23fSmrg} 3718209ff23fSmrg 3719209ff23fSmrgstatic void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 3720209ff23fSmrg{ 3721209ff23fSmrgint width, height; 3722209ff23fSmrgRADEONWaitForIdleMMIO(pScrn); 3723209ff23fSmrg 3724209ff23fSmrg/* Disable VBI capture for anything but TV tuner */ 3725209ff23fSmrgswitch(pPriv->encoding){ 3726209ff23fSmrg case 2: 3727209ff23fSmrg case 5: 3728209ff23fSmrg case 8: 3729209ff23fSmrg pPriv->capture_vbi_data=1; 3730209ff23fSmrg break; 3731209ff23fSmrg default: 3732209ff23fSmrg pPriv->capture_vbi_data=0; 3733209ff23fSmrg } 3734209ff23fSmrg 3735209ff23fSmrgswitch(pPriv->encoding){ 3736209ff23fSmrg case 1: 3737209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0); 3738209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3739209ff23fSmrg pPriv->v=25; 3740209ff23fSmrg break; 3741209ff23fSmrg case 2: 3742209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0); 3743209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3744209ff23fSmrg pPriv->v=25; 3745209ff23fSmrg break; 3746209ff23fSmrg case 3: 3747209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0); 3748209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3749209ff23fSmrg pPriv->v=25; 3750209ff23fSmrg break; 3751209ff23fSmrg case 4: 3752209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE,0); 3753209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3754209ff23fSmrg pPriv->v=23; 3755209ff23fSmrg break; 3756209ff23fSmrg case 5: 3757209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0); 3758209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3759209ff23fSmrg pPriv->v=23; 3760209ff23fSmrg break; 3761209ff23fSmrg case 6: 3762209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0); 3763209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3764209ff23fSmrg pPriv->v=23; 3765209ff23fSmrg break; 3766209ff23fSmrg case 7: 3767209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE, 0); 3768209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3769209ff23fSmrg pPriv->v=25; 3770209ff23fSmrg break; 3771209ff23fSmrg case 8: 3772209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0); 3773209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3774209ff23fSmrg pPriv->v=25; 3775209ff23fSmrg break; 3776209ff23fSmrg case 9: 3777209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0); 3778209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3779209ff23fSmrg pPriv->v=25; 3780209ff23fSmrg break; 3781209ff23fSmrg case 10: 3782209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0); 3783209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3784209ff23fSmrg pPriv->v=25; 3785209ff23fSmrg break; 3786209ff23fSmrg case 11: 3787209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0); 3788209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3789209ff23fSmrg pPriv->v=25; 3790209ff23fSmrg break; 3791209ff23fSmrg case 12: 3792209ff23fSmrg xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0); 3793209ff23fSmrg xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3794209ff23fSmrg pPriv->v=25; 3795209ff23fSmrg break; 3796209ff23fSmrg default: 3797209ff23fSmrg pPriv->v=0; 3798209ff23fSmrg return; 3799209ff23fSmrg } 3800209ff23fSmrgxf86_RT_SetInterlace(pPriv->theatre, 1); 3801209ff23fSmrgwidth = InputVideoEncodings[pPriv->encoding].width; 3802209ff23fSmrgheight = InputVideoEncodings[pPriv->encoding].height; 3803209ff23fSmrgxf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data); 3804209ff23fSmrg} 3805209ff23fSmrg 3806209ff23fSmrgstatic void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv) 3807209ff23fSmrg{ 3808209ff23fSmrgxf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 3809209ff23fSmrgswitch(pPriv->encoding){ 3810209ff23fSmrg case 1: 3811209ff23fSmrg pPriv->msp3430->standard = MSP3430_PAL; 3812209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3813209ff23fSmrg break; 3814209ff23fSmrg case 2: 3815209ff23fSmrg pPriv->msp3430->standard = MSP3430_PAL; 3816209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3817209ff23fSmrg break; 3818209ff23fSmrg case 3: 3819209ff23fSmrg pPriv->msp3430->standard = MSP3430_PAL; 3820209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3821209ff23fSmrg break; 3822209ff23fSmrg case 4: 3823209ff23fSmrg pPriv->msp3430->standard = MSP3430_NTSC; 3824209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3825209ff23fSmrg break; 3826209ff23fSmrg case 5: 3827209ff23fSmrg pPriv->msp3430->standard = MSP3430_NTSC; 3828209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3829209ff23fSmrg break; 3830209ff23fSmrg case 6: 3831209ff23fSmrg pPriv->msp3430->standard = MSP3430_NTSC; 3832209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3833209ff23fSmrg break; 3834209ff23fSmrg case 7: 3835209ff23fSmrg pPriv->msp3430->standard = MSP3430_SECAM; 3836209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3837209ff23fSmrg break; 3838209ff23fSmrg case 8: 3839209ff23fSmrg pPriv->msp3430->standard = MSP3430_SECAM; 3840209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3841209ff23fSmrg break; 3842209ff23fSmrg case 9: 3843209ff23fSmrg pPriv->msp3430->standard = MSP3430_SECAM; 3844209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3845209ff23fSmrg break; 3846209ff23fSmrg case 10: 3847209ff23fSmrg pPriv->msp3430->standard = MSP3430_SECAM; 3848209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3849209ff23fSmrg break; 3850209ff23fSmrg case 11: 3851209ff23fSmrg pPriv->msp3430->standard = MSP3430_SECAM; 3852209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3853209ff23fSmrg break; 3854209ff23fSmrg case 12: 3855209ff23fSmrg pPriv->msp3430->standard = MSP3430_SECAM; 3856209ff23fSmrg pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3857209ff23fSmrg break; 3858209ff23fSmrg default: 3859209ff23fSmrg return; 3860209ff23fSmrg } 3861209ff23fSmrgxf86_InitMSP3430(pPriv->msp3430); 3862209ff23fSmrgxf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume)); 3863209ff23fSmrg} 3864209ff23fSmrg 3865209ff23fSmrgstatic void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv) 3866209ff23fSmrg{ 3867209ff23fSmrgTDA9885Ptr t=pPriv->tda9885; 3868209ff23fSmrg 3869209ff23fSmrgswitch(pPriv->encoding){ 3870209ff23fSmrg /* PAL */ 3871209ff23fSmrg case 1: 3872209ff23fSmrg case 2: 3873209ff23fSmrg case 3: 3874209ff23fSmrg t->standard_video_if=2; 3875209ff23fSmrg t->standard_sound_carrier=1; 3876209ff23fSmrg t->modulation=2; /* negative FM */ 3877209ff23fSmrg break; 3878209ff23fSmrg /* NTSC */ 3879209ff23fSmrg case 4: 3880209ff23fSmrg case 5: 3881209ff23fSmrg case 6: 3882209ff23fSmrg t->standard_video_if=1; 3883209ff23fSmrg t->standard_sound_carrier=0; 3884209ff23fSmrg t->modulation=2; /* negative FM */ 3885209ff23fSmrg break; 3886209ff23fSmrg /* SECAM */ 3887209ff23fSmrg case 7: 3888209ff23fSmrg case 8: 3889209ff23fSmrg case 9: 3890209ff23fSmrg case 10: 3891209ff23fSmrg case 11: 3892209ff23fSmrg case 12: 3893209ff23fSmrg t->standard_video_if=0; 3894209ff23fSmrg t->standard_sound_carrier=3; 3895209ff23fSmrg t->modulation=0; /* positive AM */ 3896209ff23fSmrg break; 3897209ff23fSmrg default: 3898209ff23fSmrg return; 3899209ff23fSmrg } 3900209ff23fSmrgxf86_tda9885_setparameters(pPriv->tda9885); 3901209ff23fSmrgxf86_tda9885_getstatus(pPriv->tda9885); 3902209ff23fSmrgxf86_tda9885_dumpstatus(pPriv->tda9885); 3903209ff23fSmrg} 3904209ff23fSmrg 3905209ff23fSmrgstatic void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv) 3906209ff23fSmrg{ 3907209ff23fSmrg/* at the moment this only affect MT2032 */ 3908209ff23fSmrgswitch(pPriv->encoding){ 3909209ff23fSmrg /* PAL */ 3910209ff23fSmrg case 1: 3911209ff23fSmrg case 2: 3912209ff23fSmrg case 3: 3913209ff23fSmrg pPriv->fi1236->video_if=38.900; 3914209ff23fSmrg break; 3915209ff23fSmrg /* NTSC */ 3916209ff23fSmrg case 4: 3917209ff23fSmrg case 5: 3918209ff23fSmrg case 6: 3919209ff23fSmrg pPriv->fi1236->video_if=45.7812; 3920209ff23fSmrg pPriv->fi1236->video_if=45.750; 3921209ff23fSmrg pPriv->fi1236->video_if=45.125; 3922209ff23fSmrg break; 3923209ff23fSmrg /* SECAM */ 3924209ff23fSmrg case 7: 3925209ff23fSmrg case 8: 3926209ff23fSmrg case 9: 3927209ff23fSmrg case 10: 3928209ff23fSmrg case 11: 3929209ff23fSmrg case 12: 3930209ff23fSmrg pPriv->fi1236->video_if=58.7812; 3931209ff23fSmrg break; 3932209ff23fSmrg default: 3933209ff23fSmrg return; 3934209ff23fSmrg } 3935209ff23fSmrg} 3936209ff23fSmrg 3937