radeon_video.c revision 7821949a
1 2#ifdef HAVE_CONFIG_H 3#include "config.h" 4#endif 5 6#include <stdlib.h> 7#include <string.h> 8#include <stdio.h> 9#include <math.h> 10 11#include "radeon.h" 12#include "radeon_reg.h" 13#include "radeon_macros.h" 14#include "radeon_probe.h" 15#include "radeon_video.h" 16 17#include "xf86.h" 18#include "dixstruct.h" 19#include "atipciids.h" 20#include "xf86fbman.h" 21 22/* DPMS */ 23#ifdef HAVE_XEXTPROTO_71 24#include <X11/extensions/dpmsconst.h> 25#else 26#define DPMS_SERVER 27#include <X11/extensions/dpms.h> 28#endif 29 30#include <X11/extensions/Xv.h> 31#include "fourcc.h" 32 33#include "theatre_detect.h" 34#include "theatre_reg.h" 35#include "fi1236.h" 36#include "msp3430.h" 37#include "tda9885.h" 38 39#define OFF_DELAY 250 /* milliseconds */ 40#define FREE_DELAY 15000 41 42#define OFF_TIMER 0x01 43#define FREE_TIMER 0x02 44#define CLIENT_VIDEO_ON 0x04 45 46#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 47 48/* capture config constants */ 49#define BUF_TYPE_FIELD 0 50#define BUF_TYPE_ALTERNATING 1 51#define BUF_TYPE_FRAME 2 52 53 54#define BUF_MODE_SINGLE 0 55#define BUF_MODE_DOUBLE 1 56#define BUF_MODE_TRIPLE 2 57/* CAP0_CONFIG values */ 58 59#define FORMAT_BROOKTREE 0 60#define FORMAT_CCIR656 1 61#define FORMAT_ZV 2 62#define FORMAT_VIP16 3 63#define FORMAT_TRANSPORT 4 64 65#define ENABLE_RADEON_CAPTURE_WEAVE (RADEON_CAP0_CONFIG_CONTINUOS \ 66 | (BUF_MODE_DOUBLE <<7) \ 67 | (BUF_TYPE_FRAME << 4) \ 68 | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \ 69 | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \ 70 | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \ 71 | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422) 72 73#define ENABLE_RADEON_CAPTURE_BOB (RADEON_CAP0_CONFIG_CONTINUOS \ 74 | (BUF_MODE_SINGLE <<7) \ 75 | (BUF_TYPE_ALTERNATING << 4) \ 76 | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \ 77 | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \ 78 | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \ 79 | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422) 80 81 82static void RADEONInitOffscreenImages(ScreenPtr); 83 84static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr); 85static int RADEONPutImage(ScrnInfoPtr, short, short, short, short, short, 86 short, short, short, int, unsigned char*, short, 87 short, Bool, RegionPtr, pointer, 88 DrawablePtr); 89static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now); 90static int RADEONPutVideo(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y, 91 short src_w, short src_h, short drw_w, short drw_h, 92 RegionPtr clipBoxes, pointer data, DrawablePtr pDraw); 93 94static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv); 95static void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv); 96static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv); 97static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv); 98static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv); 99 100static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer; 101static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity; 102static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults; 103static Atom xvGamma, xvColorspace; 104static Atom xvCRTC; 105static Atom xvEncoding, xvFrequency, xvVolume, xvMute, 106 xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation, 107 xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod, 108 xvLocationID, xvDeviceID, xvInstanceID, xvDumpStatus, 109 xvAdjustment; 110 111static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode; 112 113#define GET_PORT_PRIVATE(pScrn) \ 114 (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 115 116static void 117radeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) 118{ 119 dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1; 120 dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2; 121 dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1; 122 dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2; 123 124 if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2) 125 dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; 126} 127 128static void 129radeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) 130{ 131 if (crtc->enabled) { 132 crtc_box->x1 = crtc->x; 133 crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation); 134 crtc_box->y1 = crtc->y; 135 crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation); 136 } else 137 crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; 138} 139 140static int 141radeon_box_area(BoxPtr box) 142{ 143 return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1); 144} 145 146static Bool 147radeon_crtc_is_enabled(xf86CrtcPtr crtc) 148{ 149 RADEONCrtcPrivatePtr radeon_crtc; 150 151#ifdef XF86DRM_MODE 152 if (RADEONPTR(crtc->scrn)->cs) { 153 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 154 return drmmode_crtc->dpms_mode == DPMSModeOn; 155 } 156#endif 157 158 radeon_crtc = crtc->driver_private; 159 return radeon_crtc->enabled; 160} 161 162xf86CrtcPtr 163radeon_pick_best_crtc(ScrnInfoPtr pScrn, 164 int x1, int x2, int y1, int y2) 165{ 166 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 167 int coverage, best_coverage, c; 168 BoxRec box, crtc_box, cover_box; 169 RROutputPtr primary_output = NULL; 170 xf86CrtcPtr best_crtc = NULL, primary_crtc = NULL; 171 172 if (!pScrn->vtSema) 173 return NULL; 174 175 box.x1 = x1; 176 box.x2 = x2; 177 box.y1 = y1; 178 box.y2 = y2; 179 best_coverage = 0; 180 181 /* Prefer the CRTC of the primary output */ 182#ifdef HAS_DIXREGISTERPRIVATEKEY 183 if (dixPrivateKeyRegistered(rrPrivKey)) 184#endif 185 { 186 primary_output = RRFirstOutput(pScrn->pScreen); 187 } 188 if (primary_output && primary_output->crtc) 189 primary_crtc = primary_output->crtc->devPrivate; 190 191 for (c = 0; c < xf86_config->num_crtc; c++) { 192 xf86CrtcPtr crtc = xf86_config->crtc[c]; 193 194 if (!radeon_crtc_is_enabled(crtc)) 195 continue; 196 197 radeon_crtc_box(crtc, &crtc_box); 198 radeon_box_intersect(&cover_box, &crtc_box, &box); 199 coverage = radeon_box_area(&cover_box); 200 if (coverage > best_coverage || 201 (coverage == best_coverage && crtc == primary_crtc)) { 202 best_crtc = crtc; 203 best_coverage = coverage; 204 } 205 } 206 return best_crtc; 207} 208 209#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER 210static xf86CrtcPtr 211radeon_covering_crtc(ScrnInfoPtr pScrn, 212 BoxPtr box, 213 xf86CrtcPtr desired, 214 BoxPtr crtc_box_ret) 215{ 216 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 217 xf86CrtcPtr crtc, best_crtc; 218 int coverage, best_coverage; 219 int c; 220 BoxRec crtc_box, cover_box; 221 222 best_crtc = NULL; 223 best_coverage = 0; 224 crtc_box_ret->x1 = 0; 225 crtc_box_ret->x2 = 0; 226 crtc_box_ret->y1 = 0; 227 crtc_box_ret->y2 = 0; 228 for (c = 0; c < xf86_config->num_crtc; c++) { 229 crtc = xf86_config->crtc[c]; 230 radeon_crtc_box(crtc, &crtc_box); 231 radeon_box_intersect(&cover_box, &crtc_box, box); 232 coverage = radeon_box_area(&cover_box); 233 if (coverage && crtc == desired) { 234 *crtc_box_ret = crtc_box; 235 return crtc; 236 } else if (coverage > best_coverage) { 237 *crtc_box_ret = crtc_box; 238 best_crtc = crtc; 239 best_coverage = coverage; 240 } 241 } 242 return best_crtc; 243} 244 245static Bool 246radeon_crtc_clip_video_helper(ScrnInfoPtr pScrn, 247 xf86CrtcPtr *crtc_ret, 248 xf86CrtcPtr desired_crtc, 249 BoxPtr dst, 250 INT32 *xa, 251 INT32 *xb, 252 INT32 *ya, 253 INT32 *yb, 254 RegionPtr reg, 255 INT32 width, 256 INT32 height) 257{ 258 Bool ret; 259 RegionRec crtc_region_local; 260 RegionPtr crtc_region = reg; 261 262 /* 263 * For overlay video, compute the relevant CRTC and 264 * clip video to that 265 */ 266 if (crtc_ret) { 267 BoxRec crtc_box; 268 xf86CrtcPtr crtc = radeon_covering_crtc(pScrn, dst, 269 desired_crtc, 270 &crtc_box); 271 272 if (crtc) { 273 REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1); 274 crtc_region = &crtc_region_local; 275 REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg); 276 } 277 *crtc_ret = crtc; 278 } 279 280 ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, 281 crtc_region, width, height); 282 283 if (crtc_region != reg) 284 REGION_UNINIT (pScreen, &crtc_region_local); 285 286 return ret; 287} 288#endif 289 290static Bool 291radeon_crtc_clip_video(ScrnInfoPtr pScrn, 292 xf86CrtcPtr *crtc_ret, 293 xf86CrtcPtr desired_crtc, 294 BoxPtr dst, 295 INT32 *xa, 296 INT32 *xb, 297 INT32 *ya, 298 INT32 *yb, 299 RegionPtr reg, 300 INT32 width, 301 INT32 height) 302{ 303#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER 304 return radeon_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc, 305 dst, xa, xb, ya, yb, 306 reg, width, height); 307#else 308 return xf86_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc, 309 dst, xa, xb, ya, yb, 310 reg, width, height); 311#endif 312} 313 314void RADEONInitVideo(ScreenPtr pScreen) 315{ 316 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 317 RADEONInfoPtr info = RADEONPTR(pScrn); 318 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 319 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 320 XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL; 321 int num_adaptors; 322 323 /* no overlay or 3D on RN50 */ 324 if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) 325 return; 326 327 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 328 newAdaptors = malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *)); 329 if (newAdaptors == NULL) 330 return; 331 332 memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr)); 333 adaptors = newAdaptors; 334 335 if (!IS_AVIVO_VARIANT && !info->kms_enabled) { 336 overlayAdaptor = RADEONSetupImageVideo(pScreen); 337 if (overlayAdaptor != NULL) { 338 adaptors[num_adaptors++] = overlayAdaptor; 339 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n"); 340 } else 341 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up overlay video\n"); 342 RADEONInitOffscreenImages(pScreen); 343 } 344 345 if ((info->ChipFamily < CHIP_FAMILY_RS400) 346#ifdef XF86DRI 347 || (info->directRenderingEnabled) 348#endif 349 ) { 350 texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen); 351 if (texturedAdaptor != NULL) { 352 adaptors[num_adaptors++] = texturedAdaptor; 353 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n"); 354 } else 355 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up textured video\n"); 356 } else 357 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video requires CP on R5xx/R6xx/R7xx/IGP\n"); 358 359 if(num_adaptors) 360 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 361 362 if(texturedAdaptor) { 363 XF86MCAdaptorPtr xvmcAdaptor = RADEONCreateAdaptorXvMC(pScreen, texturedAdaptor->name); 364 if(xvmcAdaptor) { 365 if(!xf86XvMCScreenInit(pScreen, 1, &xvmcAdaptor)) 366 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] Failed to initialize extension.\n"); 367 else 368 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Extension initialized.\n"); 369 } 370 } 371 372 if(newAdaptors) 373 free(newAdaptors); 374 375} 376 377/* client libraries expect an encoding */ 378static XF86VideoEncodingRec DummyEncoding = 379{ 380 0, 381 "XV_IMAGE", 382 2047, 2047, 383 {1, 1} 384}; 385 386 /* the picture is interlaced - hence the half-heights */ 387 388static XF86VideoEncodingRec 389InputVideoEncodings[] = 390{ 391 { 0, "XV_IMAGE", 2047,2047,{1,1}}, 392 { 1, "pal-composite", 720, 288, { 1, 50 }}, 393 { 2, "pal-tuner", 720, 288, { 1, 50 }}, 394 { 3, "pal-svideo", 720, 288, { 1, 50 }}, 395 { 4, "ntsc-composite", 640, 240, { 1001, 60000 }}, 396 { 5, "ntsc-tuner", 640, 240, { 1001, 60000 }}, 397 { 6, "ntsc-svideo", 640, 240, { 1001, 60000 }}, 398 { 7, "secam-composite", 720, 288, { 1, 50 }}, 399 { 8, "secam-tuner", 720, 288, { 1, 50 }}, 400 { 9, "secam-svideo", 720, 288, { 1, 50 }}, 401 { 10,"pal_60-composite", 768, 288, { 1, 50 }}, 402 { 11,"pal_60-tuner", 768, 288, { 1, 50 }}, 403 { 12,"pal_60-svideo", 768, 288, { 1, 50 }} 404}; 405 406 407#define NUM_FORMATS 12 408 409static XF86VideoFormatRec Formats[NUM_FORMATS] = 410{ 411 {8, TrueColor}, {8, DirectColor}, {8, PseudoColor}, 412 {8, GrayScale}, {8, StaticGray}, {8, StaticColor}, 413 {15, TrueColor}, {16, TrueColor}, {24, TrueColor}, 414 {15, DirectColor}, {16, DirectColor}, {24, DirectColor} 415}; 416 417 418#if 0 419#define NUM_ATTRIBUTES 9+6 420 421static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 422{ 423 {XvSettable , 0, 1, "XV_SET_DEFAULTS"}, 424 {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, 425 {XvSettable | XvGettable, 0, ~0, "XV_COLORKEY"}, 426 {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 427 {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, 428 {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, 429 {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, 430 {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"}, 431 {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}, 432 {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"}, 433 {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"}, 434 {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"}, 435 {XvSettable | XvGettable, -1, 1, "XV_CRTC"}, 436 {XvSettable | XvGettable, 100, 10000, "XV_GAMMA"}, 437 {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"}, 438}; 439 440#endif 441 442#define NUM_ATTRIBUTES 22 443#define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12) 444 445static XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] = 446{ 447 { XvGettable, 0, ~0, "XV_DEVICE_ID"}, 448 { XvGettable, 0, ~0, "XV_LOCATION_ID"}, 449 { XvGettable, 0, ~0, "XV_INSTANCE_ID"}, 450 {XvSettable , 0, 1, "XV_DUMP_STATUS"}, 451 {XvSettable , 0, 1, "XV_SET_DEFAULTS"}, 452 {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, 453 {XvSettable | XvGettable, 0, ~0,"XV_COLORKEY"}, 454 {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 455 {XvSettable | XvGettable, 0, 255, "XV_OVERLAY_ALPHA"}, 456 {XvSettable | XvGettable, 0, 255, "XV_GRAPHICS_ALPHA"}, 457 {XvSettable | XvGettable, 0, 1, "XV_ALPHA_MODE"}, 458 {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, 459 {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, 460 {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, 461 {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"}, 462 {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}, 463 {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"}, 464 {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"}, 465 {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"}, 466 {XvSettable | XvGettable, -1, 1, "XV_CRTC"}, 467 {XvSettable | XvGettable, 100, 10000, "XV_GAMMA"}, 468 {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"}, 469 470 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_BRIGHTNESS"}, 471 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_CONTRAST"}, 472 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_SATURATION"}, 473 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_HUE"}, 474 {XvSettable | XvGettable, 0, 2, "XV_OVERLAY_DEINTERLACING_METHOD"}, 475 {XvSettable | XvGettable, 0, 12, "XV_ENCODING"}, 476 {XvSettable | XvGettable, 0, -1, "XV_FREQ"}, 477 { XvGettable, -1000, 1000, "XV_TUNER_STATUS"}, 478 {XvSettable | XvGettable, -1000, 1000, "XV_VOLUME"}, 479 {XvSettable | XvGettable, 0, 1, "XV_MUTE"}, 480 {XvSettable | XvGettable, 0, 1, "XV_SAP"}, 481 {XvSettable | XvGettable, 0, 0x1F, "XV_DEBUG_ADJUSTMENT"}, 482 { 0, 0, 0, NULL} /* just a place holder so I don't have to be fancy with commas */ 483}; 484 485 486#define INCLUDE_RGB_FORMATS 1 487 488#if INCLUDE_RGB_FORMATS 489 490#define NUM_IMAGES 8 491 492/* Note: GUIDs are bogus... - but nothing uses them anyway */ 493 494#define FOURCC_RGBA32 0x41424752 495 496#define XVIMAGE_RGBA32(byte_order) \ 497 { \ 498 FOURCC_RGBA32, \ 499 XvRGB, \ 500 byte_order, \ 501 { 'R', 'G', 'B', 'A', \ 502 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 503 32, \ 504 XvPacked, \ 505 1, \ 506 32, 0x00FF0000, 0x0000FF00, 0x000000FF, \ 507 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 508 {'A', 'R', 'G', 'B', \ 509 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}, \ 510 XvTopToBottom \ 511 } 512 513#define FOURCC_RGB24 0x00000000 514 515#define XVIMAGE_RGB24 \ 516 { \ 517 FOURCC_RGB24, \ 518 XvRGB, \ 519 LSBFirst, \ 520 { 'R', 'G', 'B', 0, \ 521 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 522 24, \ 523 XvPacked, \ 524 1, \ 525 24, 0x00FF0000, 0x0000FF00, 0x000000FF, \ 526 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 527 { 'R', 'G', 'B', \ 528 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}, \ 529 XvTopToBottom \ 530 } 531 532#define FOURCC_RGBT16 0x54424752 533 534#define XVIMAGE_RGBT16(byte_order) \ 535 { \ 536 FOURCC_RGBT16, \ 537 XvRGB, \ 538 byte_order, \ 539 { 'R', 'G', 'B', 'T', \ 540 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 541 16, \ 542 XvPacked, \ 543 1, \ 544 16, 0x00007C00, 0x000003E0, 0x0000001F, \ 545 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 546 {'A', 'R', 'G', 'B', \ 547 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}, \ 548 XvTopToBottom \ 549 } 550 551#define FOURCC_RGB16 0x32424752 552 553#define XVIMAGE_RGB16(byte_order) \ 554 { \ 555 FOURCC_RGB16, \ 556 XvRGB, \ 557 byte_order, \ 558 { 'R', 'G', 'B', 0x00, \ 559 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 560 16, \ 561 XvPacked, \ 562 1, \ 563 16, 0x0000F800, 0x000007E0, 0x0000001F, \ 564 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 565 {'R', 'G', 'B', \ 566 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}, \ 567 XvTopToBottom \ 568 } 569 570static XF86ImageRec Images[NUM_IMAGES] = 571{ 572#if X_BYTE_ORDER == X_BIG_ENDIAN 573 XVIMAGE_RGBA32(MSBFirst), 574 XVIMAGE_RGBT16(MSBFirst), 575 XVIMAGE_RGB16(MSBFirst), 576#else 577 XVIMAGE_RGBA32(LSBFirst), 578 XVIMAGE_RGBT16(LSBFirst), 579 XVIMAGE_RGB16(LSBFirst), 580#endif 581 XVIMAGE_RGB24, 582 XVIMAGE_YUY2, 583 XVIMAGE_UYVY, 584 XVIMAGE_YV12, 585 XVIMAGE_I420 586}; 587 588#else 589 590#define NUM_IMAGES 4 591 592static XF86ImageRec Images[NUM_IMAGES] = 593{ 594 XVIMAGE_YUY2, 595 XVIMAGE_UYVY, 596 XVIMAGE_YV12, 597 XVIMAGE_I420 598}; 599 600#endif 601 602/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */ 603static REF_TRANSFORM trans[2] = 604{ 605 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */ 606 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */ 607}; 608 609/* Gamma curve definition for preset gammas */ 610typedef struct tagGAMMA_CURVE_R100 611{ 612 uint32_t GAMMA_0_F_SLOPE; 613 uint32_t GAMMA_0_F_OFFSET; 614 uint32_t GAMMA_10_1F_SLOPE; 615 uint32_t GAMMA_10_1F_OFFSET; 616 uint32_t GAMMA_20_3F_SLOPE; 617 uint32_t GAMMA_20_3F_OFFSET; 618 uint32_t GAMMA_40_7F_SLOPE; 619 uint32_t GAMMA_40_7F_OFFSET; 620 uint32_t GAMMA_380_3BF_SLOPE; 621 uint32_t GAMMA_380_3BF_OFFSET; 622 uint32_t GAMMA_3C0_3FF_SLOPE; 623 uint32_t GAMMA_3C0_3FF_OFFSET; 624 float OvGammaCont; 625} GAMMA_CURVE_R100; 626 627typedef struct tagGAMMA_CURVE_R200 628{ 629 uint32_t GAMMA_0_F_SLOPE; 630 uint32_t GAMMA_0_F_OFFSET; 631 uint32_t GAMMA_10_1F_SLOPE; 632 uint32_t GAMMA_10_1F_OFFSET; 633 uint32_t GAMMA_20_3F_SLOPE; 634 uint32_t GAMMA_20_3F_OFFSET; 635 uint32_t GAMMA_40_7F_SLOPE; 636 uint32_t GAMMA_40_7F_OFFSET; 637 uint32_t GAMMA_80_BF_SLOPE; 638 uint32_t GAMMA_80_BF_OFFSET; 639 uint32_t GAMMA_C0_FF_SLOPE; 640 uint32_t GAMMA_C0_FF_OFFSET; 641 uint32_t GAMMA_100_13F_SLOPE; 642 uint32_t GAMMA_100_13F_OFFSET; 643 uint32_t GAMMA_140_17F_SLOPE; 644 uint32_t GAMMA_140_17F_OFFSET; 645 uint32_t GAMMA_180_1BF_SLOPE; 646 uint32_t GAMMA_180_1BF_OFFSET; 647 uint32_t GAMMA_1C0_1FF_SLOPE; 648 uint32_t GAMMA_1C0_1FF_OFFSET; 649 uint32_t GAMMA_200_23F_SLOPE; 650 uint32_t GAMMA_200_23F_OFFSET; 651 uint32_t GAMMA_240_27F_SLOPE; 652 uint32_t GAMMA_240_27F_OFFSET; 653 uint32_t GAMMA_280_2BF_SLOPE; 654 uint32_t GAMMA_280_2BF_OFFSET; 655 uint32_t GAMMA_2C0_2FF_SLOPE; 656 uint32_t GAMMA_2C0_2FF_OFFSET; 657 uint32_t GAMMA_300_33F_SLOPE; 658 uint32_t GAMMA_300_33F_OFFSET; 659 uint32_t GAMMA_340_37F_SLOPE; 660 uint32_t GAMMA_340_37F_OFFSET; 661 uint32_t GAMMA_380_3BF_SLOPE; 662 uint32_t GAMMA_380_3BF_OFFSET; 663 uint32_t GAMMA_3C0_3FF_SLOPE; 664 uint32_t GAMMA_3C0_3FF_OFFSET; 665 float OvGammaCont; 666} GAMMA_CURVE_R200; 667 668 669/* Preset gammas */ 670static GAMMA_CURVE_R100 gamma_curve_r100[8] = 671{ 672 /* Gamma 1.0 */ 673 {0x100, 0x0, 674 0x100, 0x20, 675 0x100, 0x40, 676 0x100, 0x80, 677 0x100, 0x100, 678 0x100, 0x100, 679 1.0}, 680 /* Gamma 0.85 */ 681 {0x75, 0x0, 682 0xA2, 0xF, 683 0xAC, 0x23, 684 0xC6, 0x4E, 685 0x129, 0xD6, 686 0x12B, 0xD5, 687 1.0}, 688 /* Gamma 1.1 */ 689 {0x180, 0x0, 690 0x13C, 0x30, 691 0x13C, 0x57, 692 0x123, 0xA5, 693 0xEA, 0x116, 694 0xEA, 0x116, 695 0.9913}, 696 /* Gamma 1.2 */ 697 {0x21B, 0x0, 698 0x16D, 0x43, 699 0x172, 0x71, 700 0x13D, 0xCD, 701 0xD9, 0x128, 702 0xD6, 0x12A, 703 0.9827}, 704 /* Gamma 1.45 */ 705 {0x404, 0x0, 706 0x1B9, 0x81, 707 0x1EE, 0xB8, 708 0x16A, 0x133, 709 0xB7, 0x14B, 710 0xB2, 0x14E, 711 0.9567}, 712 /* Gamma 1.7 */ 713 {0x658, 0x0, 714 0x1B5, 0xCB, 715 0x25F, 0x102, 716 0x181, 0x199, 717 0x9C, 0x165, 718 0x98, 0x167, 719 0.9394}, 720 /* Gamma 2.2 */ 721 {0x7FF, 0x0, 722 0x625, 0x100, 723 0x1E4, 0x1C4, 724 0x1BD, 0x23D, 725 0x79, 0x187, 726 0x76, 0x188, 727 0.9135}, 728 /* Gamma 2.5 */ 729 {0x7FF, 0x0, 730 0x7FF, 0x100, 731 0x2AD, 0x200, 732 0x1A2, 0x2AB, 733 0x6E, 0x194, 734 0x67, 0x197, 735 0.9135} 736}; 737 738static GAMMA_CURVE_R200 gamma_curve_r200[8] = 739 { 740 /* Gamma 1.0 */ 741 {0x00000100, 0x00000000, 742 0x00000100, 0x00000020, 743 0x00000100, 0x00000040, 744 0x00000100, 0x00000080, 745 0x00000100, 0x00000100, 746 0x00000100, 0x00000100, 747 0x00000100, 0x00000200, 748 0x00000100, 0x00000200, 749 0x00000100, 0x00000300, 750 0x00000100, 0x00000300, 751 0x00000100, 0x00000400, 752 0x00000100, 0x00000400, 753 0x00000100, 0x00000500, 754 0x00000100, 0x00000500, 755 0x00000100, 0x00000600, 756 0x00000100, 0x00000600, 757 0x00000100, 0x00000700, 758 0x00000100, 0x00000700, 759 1.0}, 760 /* Gamma 0.85 */ 761 {0x0000001D, 0x00000000, 762 0x00000028, 0x0000000F, 763 0x00000056, 0x00000023, 764 0x000000C5, 0x0000004E, 765 0x000000DA, 0x000000B0, 766 0x000000E6, 0x000000AA, 767 0x000000F1, 0x00000190, 768 0x000000F9, 0x0000018C, 769 0x00000101, 0x00000286, 770 0x00000108, 0x00000282, 771 0x0000010D, 0x0000038A, 772 0x00000113, 0x00000387, 773 0x00000118, 0x0000049A, 774 0x0000011C, 0x00000498, 775 0x00000120, 0x000005B4, 776 0x00000124, 0x000005B2, 777 0x00000128, 0x000006D6, 778 0x0000012C, 0x000006D5, 779 1.0}, 780 /* Gamma 1.1 */ 781 {0x00000060, 0x00000000, 782 0x0000004F, 0x00000030, 783 0x0000009C, 0x00000057, 784 0x00000121, 0x000000A5, 785 0x00000113, 0x00000136, 786 0x0000010B, 0x0000013A, 787 0x00000105, 0x00000245, 788 0x00000100, 0x00000247, 789 0x000000FD, 0x00000348, 790 0x000000F9, 0x00000349, 791 0x000000F6, 0x00000443, 792 0x000000F4, 0x00000444, 793 0x000000F2, 0x00000538, 794 0x000000F0, 0x00000539, 795 0x000000EE, 0x00000629, 796 0x000000EC, 0x00000629, 797 0x000000EB, 0x00000716, 798 0x000000E9, 0x00000717, 799 0.9913}, 800 /* Gamma 1.2 */ 801 {0x00000087, 0x00000000, 802 0x0000005B, 0x00000043, 803 0x000000B7, 0x00000071, 804 0x0000013D, 0x000000CD, 805 0x00000121, 0x0000016B, 806 0x00000113, 0x00000172, 807 0x00000107, 0x00000286, 808 0x000000FF, 0x0000028A, 809 0x000000F8, 0x00000389, 810 0x000000F2, 0x0000038B, 811 0x000000ED, 0x0000047D, 812 0x000000E9, 0x00000480, 813 0x000000E5, 0x00000568, 814 0x000000E1, 0x0000056A, 815 0x000000DE, 0x0000064B, 816 0x000000DB, 0x0000064D, 817 0x000000D9, 0x00000728, 818 0x000000D6, 0x00000729, 819 0.9827}, 820 /* Gamma 1.45 */ 821 {0x00000101, 0x00000000, 822 0x0000006E, 0x00000081, 823 0x000000F7, 0x000000B8, 824 0x0000016E, 0x00000133, 825 0x00000139, 0x000001EA, 826 0x0000011B, 0x000001F9, 827 0x00000105, 0x00000314, 828 0x000000F6, 0x0000031C, 829 0x000000E9, 0x00000411, 830 0x000000DF, 0x00000417, 831 0x000000D7, 0x000004F6, 832 0x000000CF, 0x000004F9, 833 0x000000C9, 0x000005C9, 834 0x000000C4, 0x000005CC, 835 0x000000BF, 0x0000068F, 836 0x000000BA, 0x00000691, 837 0x000000B6, 0x0000074B, 838 0x000000B2, 0x0000074D, 839 0.9567}, 840 /* Gamma 1.7 */ 841 {0x00000196, 0x00000000, 842 0x0000006D, 0x000000CB, 843 0x0000012F, 0x00000102, 844 0x00000187, 0x00000199, 845 0x00000144, 0x0000025b, 846 0x00000118, 0x00000273, 847 0x000000FE, 0x0000038B, 848 0x000000E9, 0x00000395, 849 0x000000DA, 0x0000047E, 850 0x000000CE, 0x00000485, 851 0x000000C3, 0x00000552, 852 0x000000BB, 0x00000556, 853 0x000000B3, 0x00000611, 854 0x000000AC, 0x00000614, 855 0x000000A7, 0x000006C1, 856 0x000000A1, 0x000006C3, 857 0x0000009D, 0x00000765, 858 0x00000098, 0x00000767, 859 0.9394}, 860 /* Gamma 2.2 */ 861 {0x000001FF, 0x00000000, 862 0x0000018A, 0x00000100, 863 0x000000F1, 0x000001C5, 864 0x000001D6, 0x0000023D, 865 0x00000124, 0x00000328, 866 0x00000116, 0x0000032F, 867 0x000000E2, 0x00000446, 868 0x000000D3, 0x0000044D, 869 0x000000BC, 0x00000520, 870 0x000000B0, 0x00000526, 871 0x000000A4, 0x000005D6, 872 0x0000009B, 0x000005DB, 873 0x00000092, 0x00000676, 874 0x0000008B, 0x00000679, 875 0x00000085, 0x00000704, 876 0x00000080, 0x00000707, 877 0x0000007B, 0x00000787, 878 0x00000076, 0x00000789, 879 0.9135}, 880 /* Gamma 2.5 */ 881 {0x000001FF, 0x00000000, 882 0x000001FF, 0x00000100, 883 0x00000159, 0x000001FF, 884 0x000001AC, 0x000002AB, 885 0x0000012F, 0x00000381, 886 0x00000101, 0x00000399, 887 0x000000D9, 0x0000049A, 888 0x000000C3, 0x000004A5, 889 0x000000AF, 0x00000567, 890 0x000000A1, 0x0000056E, 891 0x00000095, 0x00000610, 892 0x0000008C, 0x00000614, 893 0x00000084, 0x000006A0, 894 0x0000007D, 0x000006A4, 895 0x00000077, 0x00000721, 896 0x00000071, 0x00000723, 897 0x0000006D, 0x00000795, 898 0x00000068, 0x00000797, 899 0.9135} 900}; 901 902static void 903RADEONSetOverlayGamma(ScrnInfoPtr pScrn, uint32_t gamma) 904{ 905 RADEONInfoPtr info = RADEONPTR(pScrn); 906 unsigned char *RADEONMMIO = info->MMIO; 907 908 /* Set gamma */ 909 RADEONWaitForIdleMMIO(pScrn); 910 911 if (info->ChipFamily < CHIP_FAMILY_R200) { 912 uint32_t ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL) & ~RADEON_SCALER_GAMMA_SEL_MASK; 913 OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 5)); 914 } 915 916 /* Load gamma curve adjustments */ 917 if (info->ChipFamily >= CHIP_FAMILY_R200) { 918 OUTREG(RADEON_OV0_GAMMA_000_00F, 919 (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) | 920 (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010)); 921 OUTREG(RADEON_OV0_GAMMA_010_01F, 922 (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) | 923 (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010)); 924 OUTREG(RADEON_OV0_GAMMA_020_03F, 925 (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) | 926 (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010)); 927 OUTREG(RADEON_OV0_GAMMA_040_07F, 928 (gamma_curve_r200[gamma].GAMMA_40_7F_OFFSET << 0x00000000) | 929 (gamma_curve_r200[gamma].GAMMA_40_7F_SLOPE << 0x00000010)); 930 OUTREG(RADEON_OV0_GAMMA_080_0BF, 931 (gamma_curve_r200[gamma].GAMMA_80_BF_OFFSET << 0x00000000) | 932 (gamma_curve_r200[gamma].GAMMA_80_BF_SLOPE << 0x00000010)); 933 OUTREG(RADEON_OV0_GAMMA_0C0_0FF, 934 (gamma_curve_r200[gamma].GAMMA_C0_FF_OFFSET << 0x00000000) | 935 (gamma_curve_r200[gamma].GAMMA_C0_FF_SLOPE << 0x00000010)); 936 OUTREG(RADEON_OV0_GAMMA_100_13F, 937 (gamma_curve_r200[gamma].GAMMA_100_13F_OFFSET << 0x00000000) | 938 (gamma_curve_r200[gamma].GAMMA_100_13F_SLOPE << 0x00000010)); 939 OUTREG(RADEON_OV0_GAMMA_140_17F, 940 (gamma_curve_r200[gamma].GAMMA_140_17F_OFFSET << 0x00000000) | 941 (gamma_curve_r200[gamma].GAMMA_140_17F_SLOPE << 0x00000010)); 942 OUTREG(RADEON_OV0_GAMMA_180_1BF, 943 (gamma_curve_r200[gamma].GAMMA_180_1BF_OFFSET << 0x00000000) | 944 (gamma_curve_r200[gamma].GAMMA_180_1BF_SLOPE << 0x00000010)); 945 OUTREG(RADEON_OV0_GAMMA_1C0_1FF, 946 (gamma_curve_r200[gamma].GAMMA_1C0_1FF_OFFSET << 0x00000000) | 947 (gamma_curve_r200[gamma].GAMMA_1C0_1FF_SLOPE << 0x00000010)); 948 OUTREG(RADEON_OV0_GAMMA_200_23F, 949 (gamma_curve_r200[gamma].GAMMA_200_23F_OFFSET << 0x00000000) | 950 (gamma_curve_r200[gamma].GAMMA_200_23F_SLOPE << 0x00000010)); 951 OUTREG(RADEON_OV0_GAMMA_240_27F, 952 (gamma_curve_r200[gamma].GAMMA_240_27F_OFFSET << 0x00000000) | 953 (gamma_curve_r200[gamma].GAMMA_240_27F_SLOPE << 0x00000010)); 954 OUTREG(RADEON_OV0_GAMMA_280_2BF, 955 (gamma_curve_r200[gamma].GAMMA_280_2BF_OFFSET << 0x00000000) | 956 (gamma_curve_r200[gamma].GAMMA_280_2BF_SLOPE << 0x00000010)); 957 OUTREG(RADEON_OV0_GAMMA_2C0_2FF, 958 (gamma_curve_r200[gamma].GAMMA_2C0_2FF_OFFSET << 0x00000000) | 959 (gamma_curve_r200[gamma].GAMMA_2C0_2FF_SLOPE << 0x00000010)); 960 OUTREG(RADEON_OV0_GAMMA_300_33F, 961 (gamma_curve_r200[gamma].GAMMA_300_33F_OFFSET << 0x00000000) | 962 (gamma_curve_r200[gamma].GAMMA_300_33F_SLOPE << 0x00000010)); 963 OUTREG(RADEON_OV0_GAMMA_340_37F, 964 (gamma_curve_r200[gamma].GAMMA_340_37F_OFFSET << 0x00000000) | 965 (gamma_curve_r200[gamma].GAMMA_340_37F_SLOPE << 0x00000010)); 966 OUTREG(RADEON_OV0_GAMMA_380_3BF, 967 (gamma_curve_r200[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) | 968 (gamma_curve_r200[gamma].GAMMA_380_3BF_SLOPE << 0x00000010)); 969 OUTREG(RADEON_OV0_GAMMA_3C0_3FF, 970 (gamma_curve_r200[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) | 971 (gamma_curve_r200[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010)); 972 } else { 973 OUTREG(RADEON_OV0_GAMMA_000_00F, 974 (gamma_curve_r100[gamma].GAMMA_0_F_OFFSET << 0x00000000) | 975 (gamma_curve_r100[gamma].GAMMA_0_F_SLOPE << 0x00000010)); 976 OUTREG(RADEON_OV0_GAMMA_010_01F, 977 (gamma_curve_r100[gamma].GAMMA_10_1F_OFFSET << 0x00000000) | 978 (gamma_curve_r100[gamma].GAMMA_10_1F_SLOPE << 0x00000010)); 979 OUTREG(RADEON_OV0_GAMMA_020_03F, 980 (gamma_curve_r100[gamma].GAMMA_20_3F_OFFSET << 0x00000000) | 981 (gamma_curve_r100[gamma].GAMMA_20_3F_SLOPE << 0x00000010)); 982 OUTREG(RADEON_OV0_GAMMA_040_07F, 983 (gamma_curve_r100[gamma].GAMMA_40_7F_OFFSET << 0x00000000) | 984 (gamma_curve_r100[gamma].GAMMA_40_7F_SLOPE << 0x00000010)); 985 OUTREG(RADEON_OV0_GAMMA_380_3BF, 986 (gamma_curve_r100[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) | 987 (gamma_curve_r100[gamma].GAMMA_380_3BF_SLOPE << 0x00000010)); 988 OUTREG(RADEON_OV0_GAMMA_3C0_3FF, 989 (gamma_curve_r100[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) | 990 (gamma_curve_r100[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010)); 991 } 992 993} 994 995static uint32_t 996RADEONTranslateUserGamma(uint32_t user_gamma) 997{ 998 /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */ 999 if (user_gamma <= 925) /* 0.85 */ 1000 return 1; 1001 else if (user_gamma <= 1050) /* 1.0 */ 1002 return 0; 1003 else if (user_gamma <= 1150) /* 1.1 */ 1004 return 2; 1005 else if (user_gamma <= 1325) /* 1.2 */ 1006 return 3; 1007 else if (user_gamma <= 1575) /* 1.45 */ 1008 return 4; 1009 else if (user_gamma <= 1950) /* 1.7 */ 1010 return 5; 1011 else if (user_gamma <= 2350) /* 2.2 */ 1012 return 6; 1013 else if (user_gamma > 2350) /* 2.5 */ 1014 return 7; 1015 else 1016 return 0; 1017} 1018 1019 1020/**************************************************************************** 1021 * SetTransform * 1022 * Function: Calculates and sets color space transform from supplied * 1023 * reference transform, gamma, brightness, contrast, hue and * 1024 * saturation. * 1025 * Inputs: bright - brightness * 1026 * cont - contrast * 1027 * sat - saturation * 1028 * hue - hue * 1029 * red_intensity - intensity of red component * 1030 * green_intensity - intensity of green component * 1031 * blue_intensity - intensity of blue component * 1032 * ref - index to the table of refernce transforms * 1033 * user_gamma - gamma value x 1000 (e.g., 1200 = gamma of 1.2) * 1034 * Outputs: NONE * 1035 ****************************************************************************/ 1036 1037static void RADEONSetTransform (ScrnInfoPtr pScrn, 1038 float bright, 1039 float cont, 1040 float sat, 1041 float hue, 1042 float red_intensity, 1043 float green_intensity, 1044 float blue_intensity, 1045 uint32_t ref, 1046 uint32_t user_gamma) 1047{ 1048 RADEONInfoPtr info = RADEONPTR(pScrn); 1049 unsigned char *RADEONMMIO = info->MMIO; 1050 float OvHueSin, OvHueCos; 1051 float CAdjLuma, CAdjOff; 1052 float CAdjRCb, CAdjRCr; 1053 float CAdjGCb, CAdjGCr; 1054 float CAdjBCb, CAdjBCr; 1055 float RedAdj,GreenAdj,BlueAdj; 1056 float OvLuma, OvROff, OvGOff, OvBOff; 1057 float OvRCb, OvRCr; 1058 float OvGCb, OvGCr; 1059 float OvBCb, OvBCr; 1060 float Loff = 64.0; 1061 float Coff = 512.0f; 1062 1063 uint32_t dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff; 1064 uint32_t dwOvRCb, dwOvRCr; 1065 uint32_t dwOvGCb, dwOvGCr; 1066 uint32_t dwOvBCb, dwOvBCr; 1067 uint32_t gamma = 0; 1068 1069 if (ref >= 2) 1070 return; 1071 1072 /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */ 1073 gamma = RADEONTranslateUserGamma(user_gamma); 1074 1075 if (gamma >= 8) 1076 return; 1077 1078 OvHueSin = sin(hue); 1079 OvHueCos = cos(hue); 1080 1081 CAdjLuma = cont * trans[ref].RefLuma; 1082 CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0; 1083 RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0; 1084 GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0; 1085 BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0; 1086 1087 CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr; 1088 CAdjRCr = sat * OvHueCos * trans[ref].RefRCr; 1089 CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr); 1090 CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr); 1091 CAdjBCb = sat * OvHueCos * trans[ref].RefBCb; 1092 CAdjBCr = sat * OvHueSin * trans[ref].RefBCb; 1093 1094#if 0 /* default constants */ 1095 CAdjLuma = 1.16455078125; 1096 1097 CAdjRCb = 0.0; 1098 CAdjRCr = 1.59619140625; 1099 CAdjGCb = -0.39111328125; 1100 CAdjGCr = -0.8125; 1101 CAdjBCb = 2.01708984375; 1102 CAdjBCr = 0; 1103#endif 1104 1105 OvLuma = CAdjLuma * gamma_curve_r100[gamma].OvGammaCont; 1106 OvRCb = CAdjRCb * gamma_curve_r100[gamma].OvGammaCont; 1107 OvRCr = CAdjRCr * gamma_curve_r100[gamma].OvGammaCont; 1108 OvGCb = CAdjGCb * gamma_curve_r100[gamma].OvGammaCont; 1109 OvGCr = CAdjGCr * gamma_curve_r100[gamma].OvGammaCont; 1110 OvBCb = CAdjBCb * gamma_curve_r100[gamma].OvGammaCont; 1111 OvBCr = CAdjBCr * gamma_curve_r100[gamma].OvGammaCont; 1112 OvROff = RedAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont - 1113 OvLuma * Loff - (OvRCb + OvRCr) * Coff; 1114 OvGOff = GreenAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont - 1115 OvLuma * Loff - (OvGCb + OvGCr) * Coff; 1116 OvBOff = BlueAdj + CAdjOff * gamma_curve_r100[gamma].OvGammaCont - 1117 OvLuma * Loff - (OvBCb + OvBCr) * Coff; 1118#if 0 /* default constants */ 1119 OvROff = -888.5; 1120 OvGOff = 545; 1121 OvBOff = -1104; 1122#endif 1123 1124 OvROff = ClipValue(OvROff, -2048.0, 2047.5); 1125 OvGOff = ClipValue(OvGOff, -2048.0, 2047.5); 1126 OvBOff = ClipValue(OvBOff, -2048.0, 2047.5); 1127 dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff; 1128 dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff; 1129 dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff; 1130 1131 if(info->ChipFamily == CHIP_FAMILY_RADEON) 1132 { 1133 dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17; 1134 dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1; 1135 dwOvRCr = (((INT32)(OvRCr * 2048.0))&0x7fff)<<17; 1136 dwOvGCb = (((INT32)(OvGCb * 2048.0))&0x7fff)<<1; 1137 dwOvGCr = (((INT32)(OvGCr * 2048.0))&0x7fff)<<17; 1138 dwOvBCb = (((INT32)(OvBCb * 2048.0))&0x7fff)<<1; 1139 dwOvBCr = (((INT32)(OvBCr * 2048.0))&0x7fff)<<17; 1140 } 1141 else 1142 { 1143 dwOvLuma = (((INT32)(OvLuma * 256.0))&0xfff)<<20; 1144 dwOvRCb = (((INT32)(OvRCb * 256.0))&0xfff)<<4; 1145 dwOvRCr = (((INT32)(OvRCr * 256.0))&0xfff)<<20; 1146 dwOvGCb = (((INT32)(OvGCb * 256.0))&0xfff)<<4; 1147 dwOvGCr = (((INT32)(OvGCr * 256.0))&0xfff)<<20; 1148 dwOvBCb = (((INT32)(OvBCb * 256.0))&0xfff)<<4; 1149 dwOvBCr = (((INT32)(OvBCr * 256.0))&0xfff)<<20; 1150 } 1151 1152 /* set gamma */ 1153 RADEONSetOverlayGamma(pScrn, gamma); 1154 1155 /* color transforms */ 1156 OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma); 1157 OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr); 1158 OUTREG(RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma); 1159 OUTREG(RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr); 1160 OUTREG(RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma); 1161 OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr); 1162} 1163 1164static void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode) 1165{ 1166 RADEONInfoPtr info = RADEONPTR(pScrn); 1167 unsigned char *RADEONMMIO = info->MMIO; 1168 1169 if (alpha_mode == 0) { /* key mode */ 1170 OUTREG(RADEON_OV0_KEY_CNTL, 1171 RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */ 1172 RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */ 1173 RADEON_CMP_MIX_OR); 1174 /* crtc 1 */ 1175 OUTREG(RADEON_DISP_MERGE_CNTL, 1176 (RADEON_DISP_ALPHA_MODE_KEY & 1177 RADEON_DISP_ALPHA_MODE_MASK) | 1178 ((gr_alpha << 0x00000010) & 1179 RADEON_DISP_GRPH_ALPHA_MASK) | 1180 ((ov_alpha << 0x00000018) & 1181 RADEON_DISP_OV0_ALPHA_MASK)); 1182 /* crtc 2 */ 1183 OUTREG(RADEON_DISP2_MERGE_CNTL, 1184 (RADEON_DISP_ALPHA_MODE_KEY & 1185 RADEON_DISP_ALPHA_MODE_MASK) | 1186 ((gr_alpha << 0x00000010) & 1187 RADEON_DISP_GRPH_ALPHA_MASK) | 1188 ((ov_alpha << 0x00000018) & 1189 RADEON_DISP_OV0_ALPHA_MASK)); 1190 } else { /* global mode */ 1191 OUTREG(RADEON_OV0_KEY_CNTL, 1192 RADEON_GRAPHIC_KEY_FN_FALSE | /* what does this do? */ 1193 RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */ 1194 RADEON_CMP_MIX_AND); 1195 /* crtc 2 */ 1196 OUTREG(RADEON_DISP2_MERGE_CNTL, 1197 (RADEON_DISP_ALPHA_MODE_GLOBAL & 1198 RADEON_DISP_ALPHA_MODE_MASK) | 1199 ((gr_alpha << 0x00000010) & 1200 RADEON_DISP_GRPH_ALPHA_MASK) | 1201 ((ov_alpha << 0x00000018) & 1202 RADEON_DISP_OV0_ALPHA_MASK)); 1203 /* crtc 1 */ 1204 OUTREG(RADEON_DISP_MERGE_CNTL, 1205 (RADEON_DISP_ALPHA_MODE_GLOBAL & 1206 RADEON_DISP_ALPHA_MODE_MASK) | 1207 ((gr_alpha << 0x00000010) & 1208 RADEON_DISP_GRPH_ALPHA_MASK) | 1209 ((ov_alpha << 0x00000018) & 1210 RADEON_DISP_OV0_ALPHA_MASK)); 1211 } 1212 /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */ 1213 /* not yet supported */ 1214} 1215 1216static void RADEONSetColorKey(ScrnInfoPtr pScrn, uint32_t colorKey) 1217{ 1218 RADEONInfoPtr info = RADEONPTR(pScrn); 1219 unsigned char *RADEONMMIO = info->MMIO; 1220 uint32_t min, max; 1221 uint8_t r, g, b; 1222 1223 if (info->CurrentLayout.depth > 8) 1224 { 1225 uint32_t rbits, gbits, bbits; 1226 1227 rbits = (colorKey & pScrn->mask.red) >> pScrn->offset.red; 1228 gbits = (colorKey & pScrn->mask.green) >> pScrn->offset.green; 1229 bbits = (colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 1230 1231 r = rbits << (8 - pScrn->weight.red); 1232 g = gbits << (8 - pScrn->weight.green); 1233 b = bbits << (8 - pScrn->weight.blue); 1234 } 1235 else 1236 { 1237 uint32_t bits; 1238 1239 bits = colorKey & ((1 << info->CurrentLayout.depth) - 1); 1240 r = bits; 1241 g = bits; 1242 b = bits; 1243 } 1244 min = (r << 16) | (g << 8) | (b); 1245 max = (0xff << 24) | (r << 16) | (g << 8) | (b); 1246 1247 RADEONWaitForFifo(pScrn, 2); 1248 OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max); 1249 OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min); 1250} 1251 1252void 1253RADEONResetVideo(ScrnInfoPtr pScrn) 1254{ 1255 RADEONInfoPtr info = RADEONPTR(pScrn); 1256 unsigned char *RADEONMMIO = info->MMIO; 1257 RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; 1258 char tmp[200]; 1259 1260 /* this function is called from ScreenInit. pScreen is used 1261 by XAA internally, but not valid until ScreenInit finishs. 1262 */ 1263 if (info->accelOn && pScrn->pScreen) 1264 RADEON_SYNC(info, pScrn); 1265 1266 /* this is done here because each time the server is reset these 1267 could change.. Otherwise they remain constant */ 1268 xvInstanceID = MAKE_ATOM("XV_INSTANCE_ID"); 1269 xvDeviceID = MAKE_ATOM("XV_DEVICE_ID"); 1270 xvLocationID = MAKE_ATOM("XV_LOCATION_ID"); 1271 xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS"); 1272 1273 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 1274 xvSaturation = MAKE_ATOM("XV_SATURATION"); 1275 xvColor = MAKE_ATOM("XV_COLOR"); 1276 xvContrast = MAKE_ATOM("XV_CONTRAST"); 1277 xvColorKey = MAKE_ATOM("XV_COLORKEY"); 1278 xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 1279 xvHue = MAKE_ATOM("XV_HUE"); 1280 xvRedIntensity = MAKE_ATOM("XV_RED_INTENSITY"); 1281 xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY"); 1282 xvBlueIntensity = MAKE_ATOM("XV_BLUE_INTENSITY"); 1283 xvGamma = MAKE_ATOM("XV_GAMMA"); 1284 xvColorspace = MAKE_ATOM("XV_COLORSPACE"); 1285 1286 xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); 1287 xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); 1288 xvCRTC = MAKE_ATOM("XV_CRTC"); 1289 1290 xvOvAlpha = MAKE_ATOM("XV_OVERLAY_ALPHA"); 1291 xvGrAlpha = MAKE_ATOM("XV_GRAPHICS_ALPHA"); 1292 xvAlphaMode = MAKE_ATOM("XV_ALPHA_MODE"); 1293 1294 xvOverlayDeinterlacingMethod = MAKE_ATOM("XV_OVERLAY_DEINTERLACING_METHOD"); 1295 1296 xvDecBrightness = MAKE_ATOM("XV_DEC_BRIGHTNESS"); 1297 xvDecSaturation = MAKE_ATOM("XV_DEC_SATURATION"); 1298 xvDecColor = MAKE_ATOM("XV_DEC_COLOR"); 1299 xvDecContrast = MAKE_ATOM("XV_DEC_CONTRAST"); 1300 xvDecHue = MAKE_ATOM("XV_DEC_HUE"); 1301 1302 xvEncoding = MAKE_ATOM("XV_ENCODING"); 1303 xvFrequency = MAKE_ATOM("XV_FREQ"); 1304 xvTunerStatus = MAKE_ATOM("XV_TUNER_STATUS"); 1305 xvVolume = MAKE_ATOM("XV_VOLUME"); 1306 xvMute = MAKE_ATOM("XV_MUTE"); 1307 xvSAP = MAKE_ATOM("XV_SAP"); 1308 1309 xvAdjustment = MAKE_ATOM("XV_DEBUG_ADJUSTMENT"); 1310 1311 sprintf(tmp, "RXXX:%d.%d.%d", PCI_DEV_VENDOR_ID(info->PciInfo), 1312 PCI_DEV_DEVICE_ID(info->PciInfo), PCI_DEV_REVISION(info->PciInfo)); 1313 pPriv->device_id = MAKE_ATOM(tmp); 1314 sprintf(tmp, "PCI:%02d:%02d.%d", PCI_DEV_BUS(info->PciInfo), 1315 PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo)); 1316 pPriv->location_id = MAKE_ATOM(tmp); 1317 sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex); 1318 pPriv->instance_id = MAKE_ATOM(tmp); 1319 1320 OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOFT_RESET); 1321 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0); /* maybe */ 1322 OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0); 1323 OUTREG(RADEON_OV0_FILTER_CNTL, RADEON_FILTER_PROGRAMMABLE_COEF); 1324 OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ | 1325 RADEON_VIDEO_KEY_FN_FALSE | 1326 RADEON_CMP_MIX_OR); 1327 OUTREG(RADEON_OV0_TEST, 0); 1328 OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); 1329 OUTREG(RADEON_CAP0_TRIG_CNTL, 0); 1330 RADEONSetColorKey(pScrn, pPriv->colorKey); 1331 1332 if (info->ChipFamily == CHIP_FAMILY_RADEON) { 1333 1334 OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000); 1335 OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e); 1336 OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0); 1337 OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442); 1338 OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040); 1339 OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f); 1340 1341 } else { 1342 1343 OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000); 1344 OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e); 1345 OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da); 1346 OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442); 1347 OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046); 1348 OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f); 1349 } 1350 /* 1351 * Set default Gamma ramp: 1352 * 1353 * Of 18 segments for gamma curve, all segments in R200 (and 1354 * newer) are programmable, while only lower 4 and upper 2 1355 * segments are programmable in the older Radeons. 1356 */ 1357 1358 RADEONSetOverlayGamma(pScrn, 0); /* gamma = 1.0 */ 1359 1360 if(pPriv->VIP!=NULL){ 1361 RADEONVIP_reset(pScrn,pPriv); 1362 } 1363 1364 if(pPriv->theatre != NULL) { 1365 xf86_InitTheatre(pPriv->theatre); 1366/* xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); */ 1367 } 1368 1369 if(pPriv->i2c != NULL){ 1370 RADEONResetI2C(pScrn, pPriv); 1371 } 1372} 1373 1374static void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 1375{ 1376 RADEONInfoPtr info = RADEONPTR(pScrn); 1377 RADEONPLLPtr pll = &(info->pll); 1378 TheatrePtr t; 1379 1380 uint8_t a; 1381 int i; 1382 1383 pPriv->theatre = NULL; 1384 1385 if(!info->MM_TABLE_valid && 1386 !((info->RageTheatreCrystal>=0) && 1387 (info->RageTheatreTunerPort>=0) && (info->RageTheatreCompositePort>=0) && 1388 (info->RageTheatreSVideoPort>=0))) 1389 { 1390 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no multimedia table present, disabling Rage Theatre.\n"); 1391 return; 1392 } 1393 1394 /* Go and find Rage Theatre, if it exists */ 1395 1396 if (info->IsMobility) 1397 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n"); 1398 else 1399 pPriv->theatre=xf86_DetectTheatre(pPriv->VIP); 1400 1401 if(pPriv->theatre==NULL)return; 1402 1403 /* just a matter of convenience */ 1404 t=pPriv->theatre; 1405 1406 t->video_decoder_type=info->video_decoder_type; 1407 1408 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type is 0x%04x (BIOS value) versus 0x%04x (current PLL setting)\n", 1409 t->video_decoder_type, pll->xclk); 1410 1411 if(info->MM_TABLE_valid){ 1412 for(i=0;i<5;i++){ 1413 a=info->MM_TABLE.input[i]; 1414 1415 switch(a & 0x3){ 1416 case 1: 1417 t->wTunerConnector=i; 1418 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tuner is on port %d\n",i); 1419 break; 1420 case 2: if(a & 0x4){ 1421 t->wComp0Connector=RT_COMP2; 1422 } else { 1423 t->wComp0Connector=RT_COMP1; 1424 } 1425 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector); 1426 break; 1427 case 3: if(a & 0x4){ 1428 t->wSVideo0Connector=RT_YCR_COMP4; 1429 } else { 1430 t->wSVideo0Connector=RT_YCF_COMP4; 1431 } 1432 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector); 1433 break; 1434 default: 1435 break; 1436 } 1437 } 1438 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n", 1439 (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector); 1440 1441 } 1442 1443 if(info->RageTheatreTunerPort>=0)t->wTunerConnector=info->RageTheatreTunerPort; 1444 if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort; 1445 if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort; 1446 1447 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n", 1448 (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector); 1449 1450 switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){ 1451 case 2700: 1452 t->video_decoder_type=RT_FREF_2700; 1453 break; 1454 case 2950: 1455 t->video_decoder_type=RT_FREF_2950; 1456 break; 1457 default: 1458 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1459 "Unsupported reference clock frequency, Rage Theatre disabled\n"); 1460 t->theatre_num=-1; 1461 free(pPriv->theatre); 1462 pPriv->theatre = NULL; 1463 return; 1464 } 1465 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type used: 0x%04x\n", t->video_decoder_type); 1466} 1467 1468static XF86VideoAdaptorPtr 1469RADEONAllocAdaptor(ScrnInfoPtr pScrn) 1470{ 1471 XF86VideoAdaptorPtr adapt; 1472 RADEONInfoPtr info = RADEONPTR(pScrn); 1473 RADEONPortPrivPtr pPriv; 1474 uint32_t dot_clock; 1475 int ecp; 1476 1477 if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn))) 1478 return NULL; 1479 1480 if(!(pPriv = calloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion)))) 1481 { 1482 free(adapt); 1483 return NULL; 1484 } 1485 1486 adapt->pPortPrivates = (DevUnion*)(&pPriv[1]); 1487 adapt->pPortPrivates[0].ptr = (pointer)pPriv; 1488 1489 pPriv->colorKey = info->videoKey; 1490 pPriv->doubleBuffer = TRUE; 1491 pPriv->videoStatus = 0; 1492 pPriv->brightness = 0; 1493 pPriv->transform_index = 0; 1494 pPriv->saturation = 0; 1495 pPriv->contrast = 0; 1496 pPriv->red_intensity = 0; 1497 pPriv->green_intensity = 0; 1498 pPriv->blue_intensity = 0; 1499 pPriv->hue = 0; 1500 pPriv->currentBuffer = 0; 1501 pPriv->autopaint_colorkey = TRUE; 1502 pPriv->gamma = 1000; 1503 pPriv->desired_crtc = NULL; 1504 1505 pPriv->ov_alpha = 255; 1506 pPriv->gr_alpha = 255; 1507 pPriv->alpha_mode = 0; 1508 1509 /* TV-in stuff */ 1510 pPriv->video_stream_active = FALSE; 1511 pPriv->encoding = 4; 1512 pPriv->frequency = 1000; 1513 pPriv->volume = -1000; 1514 pPriv->mute = TRUE; 1515 pPriv->v = 0; 1516 pPriv->overlay_deinterlacing_method = METHOD_BOB; 1517 pPriv->capture_vbi_data = 0; 1518 pPriv->dec_brightness = 0; 1519 pPriv->dec_saturation = 0; 1520 pPriv->dec_contrast = 0; 1521 pPriv->dec_hue = 0; 1522 1523 1524 /* 1525 * Unlike older Mach64 chips, RADEON has only two ECP settings: 1526 * 0 for PIXCLK < 175Mhz, and 1 (divide by 2) 1527 * for higher clocks, sure makes life nicer 1528 */ 1529 dot_clock = info->ModeReg->dot_clock_freq; 1530 1531 if (dot_clock < 17500) 1532 info->ecp_div = 0; 1533 else 1534 info->ecp_div = 1; 1535 ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8); 1536 1537 if (info->IsIGP) { 1538 /* Force the overlay clock on for integrated chips 1539 */ 1540 ecp |= (1<<18); 1541 } 1542 1543 OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp); 1544 1545 1546 /* Decide on tuner type */ 1547 if((info->tunerType<0) && (info->MM_TABLE_valid)) { 1548 pPriv->tuner_type = info->MM_TABLE.tuner_type; 1549 } else 1550 pPriv->tuner_type = info->tunerType; 1551 1552 /* Initialize I2C bus */ 1553 RADEONInitI2C(pScrn, pPriv); 1554 if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv); 1555 1556 1557 #if 0 /* this is just here for easy debugging - normally off */ 1558 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n"); 1559 for(i=0;i<255;i+=2) 1560 if(RADEONProbeAddress(pPriv->i2c, i)) 1561 xf86DrvMsg(pScrn->scrnIndex, X_INFO, " found device at address 0x%02x\n", i); 1562 #endif 1563 1564 /* resetting the VIP bus causes problems with some mobility chips. 1565 * we don't support video in on any mobility chips at the moment anyway 1566 */ 1567 /* Initialize VIP bus */ 1568 if (!info->IsMobility) 1569 RADEONVIP_init(pScrn, pPriv); 1570 1571 info->adaptor = adapt; 1572 info->xv_max_width = 2047; 1573 info->xv_max_height = 2047; 1574 1575 if(!xf86LoadSubModule(pScrn,"theatre_detect")) 1576 { 1577 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n"); 1578 goto skip_theatre; 1579 } 1580 RADEONSetupTheatre(pScrn, pPriv); 1581 1582 /* 1583 * Now load the correspondind theatre chip based on what has been detected. 1584 */ 1585 if (pPriv->theatre) 1586 { 1587 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Going to load the corresponding theatre module\n"); 1588 switch (pPriv->theatre->theatre_id) 1589 { 1590 case RT100_ATI_ID: 1591 { 1592 if(!xf86LoadSubModule(pScrn,"theatre")) 1593 { 1594 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n"); 1595 free(pPriv->theatre); 1596 goto skip_theatre; 1597 } 1598 break; 1599 } 1600 case RT200_ATI_ID: 1601 { 1602 if(!xf86LoadSubModule(pScrn,"theatre200")) 1603 { 1604 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n"); 1605 free(pPriv->theatre); 1606 goto skip_theatre; 1607 } 1608 pPriv->theatre->microc_path = info->RageTheatreMicrocPath; 1609 pPriv->theatre->microc_type = info->RageTheatreMicrocType; 1610 break; 1611 } 1612 default: 1613 { 1614 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unknown Theatre chip\n"); 1615 free(pPriv->theatre); 1616 goto skip_theatre; 1617 } 1618 } 1619 } 1620 1621 if(pPriv->theatre!=NULL) 1622 { 1623 xf86_InitTheatre(pPriv->theatre); 1624 if(pPriv->theatre->mode == MODE_UNINITIALIZED) 1625 { 1626 free(pPriv->theatre); 1627 pPriv->theatre = NULL; 1628 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Rage Theatre disabled\n"); 1629 /* Here the modules must be unloaded */ 1630 goto skip_theatre; 1631 } 1632 } 1633 1634 if(pPriv->theatre!=NULL){ 1635 xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); 1636 xf86_RT_SetTint(pPriv->theatre, pPriv->dec_hue); 1637 xf86_RT_SetSaturation(pPriv->theatre, pPriv->dec_saturation); 1638 xf86_RT_SetSharpness(pPriv->theatre, RT_NORM_SHARPNESS); 1639 xf86_RT_SetContrast(pPriv->theatre, pPriv->dec_contrast); 1640 xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness); 1641 1642 RADEON_RT_SetEncoding(pScrn, pPriv); 1643 } 1644 1645skip_theatre: 1646 1647 return adapt; 1648} 1649 1650static XF86VideoAdaptorPtr 1651RADEONSetupImageVideo(ScreenPtr pScreen) 1652{ 1653 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1654 RADEONPortPrivPtr pPriv; 1655 XF86VideoAdaptorPtr adapt; 1656 1657 if(!(adapt = RADEONAllocAdaptor(pScrn))) 1658 return NULL; 1659 1660 adapt->type = XvWindowMask | XvInputMask | XvImageMask; 1661 adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/; 1662 adapt->name = "ATI Radeon Video Overlay"; 1663 adapt->nEncodings = 1; 1664 adapt->pEncodings = &DummyEncoding; 1665 adapt->nFormats = NUM_FORMATS; 1666 adapt->pFormats = Formats; 1667 adapt->nPorts = 1; 1668 adapt->nAttributes = NUM_ATTRIBUTES; 1669 adapt->pAttributes = Attributes; 1670 adapt->nImages = NUM_IMAGES; 1671 adapt->pImages = Images; 1672 adapt->PutVideo = NULL; 1673 adapt->PutStill = NULL; 1674 adapt->GetVideo = NULL; 1675 adapt->GetStill = NULL; 1676 adapt->StopVideo = RADEONStopVideo; 1677 adapt->SetPortAttribute = RADEONSetPortAttribute; 1678 adapt->GetPortAttribute = RADEONGetPortAttribute; 1679 adapt->QueryBestSize = RADEONQueryBestSize; 1680 adapt->PutImage = RADEONPutImage; 1681 adapt->QueryImageAttributes = RADEONQueryImageAttributes; 1682 1683 pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr); 1684 REGION_NULL(pScreen, &(pPriv->clip)); 1685 1686 pPriv->textured = FALSE; 1687 1688 if(pPriv->theatre != NULL) { 1689 /* video decoder is present, extend capabilities */ 1690 adapt->nEncodings = 13; 1691 adapt->pEncodings = InputVideoEncodings; 1692 adapt->type |= XvVideoMask; 1693 adapt->nAttributes = NUM_DEC_ATTRIBUTES; 1694 adapt->PutVideo = RADEONPutVideo; 1695 } 1696 1697 RADEONResetVideo(pScrn); 1698 1699 return adapt; 1700} 1701 1702void 1703RADEONFreeVideoMemory(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 1704{ 1705 RADEONInfoPtr info = RADEONPTR(pScrn); 1706 1707 if (pPriv->video_memory != NULL) { 1708 radeon_legacy_free_memory(pScrn, pPriv->video_memory); 1709 pPriv->video_memory = NULL; 1710 1711 if (info->cs && pPriv->textured) { 1712 pPriv->src_bo[0] = NULL; 1713 radeon_legacy_free_memory(pScrn, pPriv->src_bo[1]); 1714 pPriv->src_bo[1] = NULL; 1715 } 1716 } 1717} 1718 1719void 1720RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup) 1721{ 1722 RADEONInfoPtr info = RADEONPTR(pScrn); 1723 unsigned char *RADEONMMIO = info->MMIO; 1724 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1725 1726 if (pPriv->textured) { 1727 if (cleanup) { 1728 RADEONFreeVideoMemory(pScrn, pPriv); 1729 } 1730 return; 1731 } 1732 1733 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1734 1735 if(cleanup) { 1736 if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1737 RADEONWaitForFifo(pScrn, 2); 1738 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 1739 } 1740 if(pPriv->video_stream_active){ 1741 RADEONWaitForFifo(pScrn, 2); 1742 OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); 1743 OUTREG(RADEON_CAP0_TRIG_CNTL, 0); 1744 RADEONResetVideo(pScrn); 1745 pPriv->video_stream_active = FALSE; 1746 if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 1747 if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE); 1748 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1749 } 1750 RADEONFreeVideoMemory(pScrn, pPriv); 1751 pPriv->videoStatus = 0; 1752 } else { 1753 if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1754 pPriv->videoStatus |= OFF_TIMER; 1755 pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 1756 } 1757 } 1758} 1759 1760int 1761RADEONSetPortAttribute(ScrnInfoPtr pScrn, 1762 Atom attribute, 1763 INT32 value, 1764 pointer data) 1765{ 1766 RADEONInfoPtr info = RADEONPTR(pScrn); 1767 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1768 Bool setTransform = FALSE; 1769 Bool setAlpha = FALSE; 1770 unsigned char *RADEONMMIO = info->MMIO; 1771 1772 RADEON_SYNC(info, pScrn); 1773 1774 if(attribute == xvAutopaintColorkey) 1775 { 1776 pPriv->autopaint_colorkey = ClipValue (value, 0, 1); 1777 } 1778 else if(attribute == xvSetDefaults) 1779 { 1780 pPriv->autopaint_colorkey = TRUE; 1781 pPriv->brightness = 0; 1782 pPriv->saturation = 0; 1783 pPriv->contrast = 0; 1784 pPriv->hue = 0; 1785 pPriv->red_intensity = 0; 1786 pPriv->green_intensity = 0; 1787 pPriv->blue_intensity = 0; 1788 pPriv->gamma = 1000; 1789 pPriv->transform_index = 0; 1790 pPriv->doubleBuffer = FALSE; 1791 pPriv->ov_alpha = 255; 1792 pPriv->gr_alpha = 255; 1793 pPriv->alpha_mode = 0; 1794 1795 /* It is simpler to call itself */ 1796 RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data); 1797 RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data); 1798 RADEONSetPortAttribute(pScrn, xvDecContrast, 0, data); 1799 RADEONSetPortAttribute(pScrn, xvDecHue, 0, data); 1800 1801 RADEONSetPortAttribute(pScrn, xvVolume, -1000, data); 1802 RADEONSetPortAttribute(pScrn, xvMute, 1, data); 1803 RADEONSetPortAttribute(pScrn, xvSAP, 0, data); 1804 RADEONSetPortAttribute(pScrn, xvDoubleBuffer, 1, data); 1805 1806 setTransform = TRUE; 1807 setAlpha = TRUE; 1808 } 1809 else if(attribute == xvBrightness) 1810 { 1811 pPriv->brightness = ClipValue (value, -1000, 1000); 1812 setTransform = TRUE; 1813 } 1814 else if((attribute == xvSaturation) || (attribute == xvColor)) 1815 { 1816 pPriv->saturation = ClipValue (value, -1000, 1000); 1817 setTransform = TRUE; 1818 } 1819 else if(attribute == xvContrast) 1820 { 1821 pPriv->contrast = ClipValue (value, -1000, 1000); 1822 setTransform = TRUE; 1823 } 1824 else if(attribute == xvHue) 1825 { 1826 pPriv->hue = ClipValue (value, -1000, 1000); 1827 setTransform = TRUE; 1828 } 1829 else if(attribute == xvRedIntensity) 1830 { 1831 pPriv->red_intensity = ClipValue (value, -1000, 1000); 1832 setTransform = TRUE; 1833 } 1834 else if(attribute == xvGreenIntensity) 1835 { 1836 pPriv->green_intensity = ClipValue (value, -1000, 1000); 1837 setTransform = TRUE; 1838 } 1839 else if(attribute == xvBlueIntensity) 1840 { 1841 pPriv->blue_intensity = ClipValue (value, -1000, 1000); 1842 setTransform = TRUE; 1843 } 1844 else if(attribute == xvGamma) 1845 { 1846 pPriv->gamma = ClipValue (value, 100, 10000); 1847 setTransform = TRUE; 1848 } 1849 else if(attribute == xvColorspace) 1850 { 1851 pPriv->transform_index = ClipValue (value, 0, 1); 1852 setTransform = TRUE; 1853 } 1854 else if(attribute == xvDoubleBuffer) 1855 { 1856 pPriv->doubleBuffer = ClipValue (value, 0, 1); 1857 } 1858 else if(attribute == xvColorKey) 1859 { 1860 pPriv->colorKey = value; 1861 RADEONSetColorKey (pScrn, pPriv->colorKey); 1862 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1863 } 1864 else if(attribute == xvCRTC) 1865 { 1866 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1867 if ((value < -1) || (value > xf86_config->num_crtc)) 1868 return BadValue; 1869 if (value < 0) 1870 pPriv->desired_crtc = NULL; 1871 else 1872 pPriv->desired_crtc = xf86_config->crtc[value]; 1873 } 1874 else if(attribute == xvOvAlpha) 1875 { 1876 pPriv->ov_alpha = ClipValue (value, 0, 255); 1877 setAlpha = TRUE; 1878 } 1879 else if(attribute == xvGrAlpha) 1880 { 1881 pPriv->gr_alpha = ClipValue (value, 0, 255); 1882 setAlpha = TRUE; 1883 } 1884 else if(attribute == xvAlphaMode) 1885 { 1886 pPriv->alpha_mode = ClipValue (value, 0, 1); 1887 setAlpha = TRUE; 1888 } 1889 else if(attribute == xvDecBrightness) 1890 { 1891 pPriv->dec_brightness = value; 1892 if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness); 1893 } 1894 else if((attribute == xvDecSaturation) || (attribute == xvDecColor)) 1895 { 1896 if(value<-1000)value = -1000; 1897 if(value>1000)value = 1000; 1898 pPriv->dec_saturation = value; 1899 if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value); 1900 } 1901 else if(attribute == xvDecContrast) 1902 { 1903 pPriv->dec_contrast = value; 1904 if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value); 1905 } 1906 else if(attribute == xvDecHue) 1907 { 1908 pPriv->dec_hue = value; 1909 if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value); 1910 } 1911 else if(attribute == xvEncoding) 1912 { 1913 pPriv->encoding = value; 1914 if(pPriv->video_stream_active) 1915 { 1916 if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv); 1917 if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv); 1918 if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv); 1919 if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv); 1920 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1921 /* put more here to actually change it */ 1922 } 1923 } 1924 else if(attribute == xvFrequency) 1925 { 1926 pPriv->frequency = value; 1927 /* mute volume if it was not muted before */ 1928 if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 1929 if((pPriv->uda1380!=NULL)&& !pPriv->mute)xf86_uda1380_mute(pPriv->uda1380, TRUE); 1930 if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value); 1931/* if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv); */ 1932 if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck)) 1933 xf86_InitMSP3430(pPriv->msp3430); 1934 if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume)); 1935 if((pPriv->uda1380 != NULL)&& !pPriv->mute) xf86_uda1380_setvolume(pPriv->uda1380, pPriv->volume); 1936 } 1937 else if(attribute == xvMute) 1938 { 1939 pPriv->mute = value; 1940 if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume)); 1941 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1942 if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, pPriv->mute); 1943 } 1944 else if(attribute == xvSAP) 1945 { 1946 pPriv->sap_channel = value; 1947 if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3); 1948 } 1949 else if(attribute == xvVolume) 1950 { 1951 if(value<-1000)value = -1000; 1952 if(value>1000)value = 1000; 1953 pPriv->volume = value; 1954 pPriv->mute = FALSE; 1955 if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value)); 1956 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1957 if(pPriv->uda1380 != NULL) xf86_uda1380_setvolume(pPriv->uda1380, value); 1958 } 1959 else if(attribute == xvOverlayDeinterlacingMethod) 1960 { 1961 if(value<0)value = 0; 1962 if(value>2)value = 2; 1963 pPriv->overlay_deinterlacing_method = value; 1964 switch(pPriv->overlay_deinterlacing_method){ 1965 case METHOD_BOB: 1966 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 1967 break; 1968 case METHOD_SINGLE: 1969 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28)); 1970 break; 1971 case METHOD_WEAVE: 1972 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0); 1973 break; 1974 default: 1975 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 1976 } 1977 } 1978 else if(attribute == xvDumpStatus) 1979 { 1980 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n", 1981 pScrn->currentMode->Flags, 1982 pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" , 1983 pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : "" 1984 ); 1985 if(pPriv->tda9885 != NULL){ 1986 xf86_tda9885_getstatus(pPriv->tda9885); 1987 xf86_tda9885_dumpstatus(pPriv->tda9885); 1988 } 1989 if(pPriv->fi1236!=NULL){ 1990 xf86_fi1236_dump_status(pPriv->fi1236); 1991 } 1992 } 1993 else if(attribute == xvAdjustment) 1994 { 1995 pPriv->adjustment=value; 1996 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n", 1997 (unsigned)pPriv->adjustment); 1998 if(pPriv->tda9885!=0){ 1999 pPriv->tda9885->top_adjustment=value; 2000 RADEON_TDA9885_SetEncoding(pPriv); 2001 } 2002 } 2003 else 2004 return BadMatch; 2005 2006 if (setTransform) 2007 { 2008 RADEONSetTransform(pScrn, 2009 RTFBrightness(pPriv->brightness), 2010 RTFContrast(pPriv->contrast), 2011 RTFSaturation(pPriv->saturation), 2012 RTFHue(pPriv->hue), 2013 RTFIntensity(pPriv->red_intensity), 2014 RTFIntensity(pPriv->green_intensity), 2015 RTFIntensity(pPriv->blue_intensity), 2016 pPriv->transform_index, 2017 pPriv->gamma); 2018 } 2019 2020 if (setAlpha) 2021 { 2022 RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode); 2023 } 2024 2025 return Success; 2026} 2027 2028int 2029RADEONGetPortAttribute(ScrnInfoPtr pScrn, 2030 Atom attribute, 2031 INT32 *value, 2032 pointer data) 2033{ 2034 RADEONInfoPtr info = RADEONPTR(pScrn); 2035 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 2036 2037 if (info->accelOn) RADEON_SYNC(info, pScrn); 2038 2039 if(attribute == xvAutopaintColorkey) 2040 *value = pPriv->autopaint_colorkey; 2041 else if(attribute == xvBrightness) 2042 *value = pPriv->brightness; 2043 else if((attribute == xvSaturation) || (attribute == xvColor)) 2044 *value = pPriv->saturation; 2045 else if(attribute == xvContrast) 2046 *value = pPriv->contrast; 2047 else if(attribute == xvHue) 2048 *value = pPriv->hue; 2049 else if(attribute == xvRedIntensity) 2050 *value = pPriv->red_intensity; 2051 else if(attribute == xvGreenIntensity) 2052 *value = pPriv->green_intensity; 2053 else if(attribute == xvBlueIntensity) 2054 *value = pPriv->blue_intensity; 2055 else if(attribute == xvGamma) 2056 *value = pPriv->gamma; 2057 else if(attribute == xvColorspace) 2058 *value = pPriv->transform_index; 2059 else if(attribute == xvDoubleBuffer) 2060 *value = pPriv->doubleBuffer ? 1 : 0; 2061 else if(attribute == xvColorKey) 2062 *value = pPriv->colorKey; 2063 else if(attribute == xvCRTC) { 2064 int c; 2065 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2066 for (c = 0; c < xf86_config->num_crtc; c++) 2067 if (xf86_config->crtc[c] == pPriv->desired_crtc) 2068 break; 2069 if (c == xf86_config->num_crtc) 2070 c = -1; 2071 *value = c; 2072 } 2073 else if(attribute == xvOvAlpha) 2074 *value = pPriv->ov_alpha; 2075 else if(attribute == xvGrAlpha) 2076 *value = pPriv->gr_alpha; 2077 else if(attribute == xvAlphaMode) 2078 *value = pPriv->alpha_mode; 2079 else if(attribute == xvDecBrightness) 2080 *value = pPriv->dec_brightness; 2081 else if((attribute == xvDecSaturation) || (attribute == xvDecColor)) 2082 *value = pPriv->dec_saturation; 2083 else if(attribute == xvDecContrast) 2084 *value = pPriv->dec_contrast; 2085 else if(attribute == xvDecHue) 2086 *value = pPriv->dec_hue; 2087 else if(attribute == xvEncoding) 2088 *value = pPriv->encoding; 2089 else if(attribute == xvFrequency) 2090 *value = pPriv->frequency; 2091 else 2092 if(attribute == xvTunerStatus) { 2093 if(pPriv->fi1236==NULL){ 2094 *value=TUNER_OFF; 2095 } else 2096 { 2097 *value = xf86_TUNER_get_afc_hint(pPriv->fi1236); 2098 } 2099 } 2100 else if(attribute == xvMute) 2101 *value = pPriv->mute; 2102 else if(attribute == xvSAP) 2103 *value = pPriv->sap_channel; 2104 else if(attribute == xvVolume) 2105 *value = pPriv->volume; 2106 else if(attribute == xvOverlayDeinterlacingMethod) 2107 *value = pPriv->overlay_deinterlacing_method; 2108 else if(attribute == xvDeviceID) 2109 *value = pPriv->device_id; 2110 else if(attribute == xvLocationID) 2111 *value = pPriv->location_id; 2112 else if(attribute == xvInstanceID) 2113 *value = pPriv->instance_id; 2114 else if(attribute == xvAdjustment) 2115 *value = pPriv->adjustment; 2116 else 2117 return BadMatch; 2118 2119 return Success; 2120} 2121 2122void 2123RADEONQueryBestSize( 2124 ScrnInfoPtr pScrn, 2125 Bool motion, 2126 short vid_w, short vid_h, 2127 short drw_w, short drw_h, 2128 unsigned int *p_w, unsigned int *p_h, 2129 pointer data 2130){ 2131 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 2132 2133 if (!pPriv->textured) { 2134 if (vid_w > (drw_w << 4)) 2135 drw_w = vid_w >> 4; 2136 if (vid_h > (drw_h << 4)) 2137 drw_h = vid_h >> 4; 2138 } 2139 2140 *p_w = drw_w; 2141 *p_h = drw_h; 2142} 2143 2144static struct { 2145 double range; 2146 signed char coeff[5][4]; 2147 } TapCoeffs[]= 2148 { 2149 {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2150 {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2151 {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2152 {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2153 {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2154 {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2155 {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2156 {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2157 {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2158 {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2159 {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2160 {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2161 {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2162 {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2163 {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2164 {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2165 {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2166 {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2167 {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2168 {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2169 {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2170 {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2171 {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2172 {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2173 {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2174 {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2175 {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }}, 2176 {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2177 {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2178 {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2179 {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }}, 2180 {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2181 {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2182 {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2183 {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2184 {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2185 {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2186 {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2187 {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2188 {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2189 {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2190 {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2191 {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2192 {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2193 {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2194 {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2195 {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2196 {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2197 {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2198 {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2199 {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2200 {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2201 {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, 2202 {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, 2203 {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2204 {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2205 {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2206 {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }}, 2207 {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2208 {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2209 {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2210 {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2211 {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2212 {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2213 {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2214 {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2215 {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2216 {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2217 {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2218 {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2219 {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2220 {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2221 {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2222 {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2223 {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}, 2224 {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }} 2225 }; 2226 2227void 2228RADEONCopyData( 2229 ScrnInfoPtr pScrn, 2230 unsigned char *src, 2231 unsigned char *dst, 2232 unsigned int srcPitch, 2233 unsigned int dstPitch, 2234 unsigned int h, 2235 unsigned int w, 2236 unsigned int bpp 2237){ 2238 RADEONInfoPtr info = RADEONPTR(pScrn); 2239 2240 /* Get the byte-swapping right for big endian systems */ 2241 if ( bpp == 2 ) { 2242 w *= 2; 2243 bpp = 1; 2244 } 2245 2246#ifdef XF86DRI 2247 2248 if ( info->directRenderingEnabled && info->DMAForXv ) 2249 { 2250 uint8_t *buf; 2251 uint32_t bufPitch, dstPitchOff; 2252 int x, y; 2253 unsigned int hpass; 2254 2255 RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y ); 2256 2257 while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch, 2258 x, &y, &h, &hpass )) ) 2259 { 2260 RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch, 2261 srcPitch ); 2262 src += hpass * srcPitch; 2263 } 2264 2265 FLUSH_RING(); 2266 2267 return; 2268 } 2269 else 2270#endif /* XF86DRI */ 2271 { 2272 int swap = RADEON_HOST_DATA_SWAP_NONE; 2273 2274#if X_BYTE_ORDER == X_BIG_ENDIAN 2275 if (info->kms_enabled) { 2276 switch(bpp) { 2277 case 2: 2278 swap = RADEON_HOST_DATA_SWAP_16BIT; 2279 break; 2280 case 4: 2281 swap = RADEON_HOST_DATA_SWAP_32BIT; 2282 break; 2283 } 2284 } else { 2285 switch (pScrn->bitsPerPixel) { 2286 case 16: 2287 swap = RADEON_HOST_DATA_SWAP_16BIT; 2288 break; 2289 case 32: 2290 swap = RADEON_HOST_DATA_SWAP_32BIT; 2291 break; 2292 } 2293 } 2294#endif 2295 2296 w *= bpp; 2297 2298 if (dstPitch == w && dstPitch == srcPitch) 2299 RADEONCopySwap(dst, src, h * dstPitch, swap); 2300 else { 2301 while (h--) { 2302 RADEONCopySwap(dst, src, w, swap); 2303 src += srcPitch; 2304 dst += dstPitch; 2305 } 2306 } 2307 } 2308} 2309 2310static void 2311RADEONCopyRGB24Data( 2312 ScrnInfoPtr pScrn, 2313 unsigned char *src, 2314 unsigned char *dst, 2315 unsigned int srcPitch, 2316 unsigned int dstPitch, 2317 unsigned int h, 2318 unsigned int w 2319){ 2320 uint32_t *dptr; 2321 uint8_t *sptr; 2322 int i,j; 2323 RADEONInfoPtr info = RADEONPTR(pScrn); 2324#ifdef XF86DRI 2325 2326 if ( info->directRenderingEnabled && info->DMAForXv ) 2327 { 2328 uint32_t bufPitch, dstPitchOff; 2329 int x, y; 2330 unsigned int hpass; 2331 2332 RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y ); 2333 2334 while ( (dptr = ( uint32_t* )RADEONHostDataBlit( pScrn, 4, w, dstPitchOff, 2335 &bufPitch, x, &y, &h, 2336 &hpass )) ) 2337 { 2338 for( j = 0; j < hpass; j++ ) 2339 { 2340 sptr = src; 2341 2342 for ( i = 0 ; i < w; i++, sptr += 3 ) 2343 { 2344 dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0]; 2345 } 2346 2347 src += srcPitch; 2348 dptr += bufPitch / 4; 2349 } 2350 } 2351 2352 FLUSH_RING(); 2353 2354 return; 2355 } 2356 else 2357#endif /* XF86DRI */ 2358 { 2359#if X_BYTE_ORDER == X_BIG_ENDIAN 2360 unsigned char *RADEONMMIO = info->MMIO; 2361 2362 if (!info->kms_enabled) 2363 OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl & 2364 ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP)); 2365#endif 2366 2367 for (j = 0; j < h; j++) { 2368 dptr = (uint32_t *)(dst + j * dstPitch); 2369 sptr = src + j * srcPitch; 2370 2371 for (i = 0; i < w; i++, sptr += 3) { 2372 dptr[i] = cpu_to_le32((sptr[2] << 16) | (sptr[1] << 8) | sptr[0]); 2373 } 2374 } 2375 2376#if X_BYTE_ORDER == X_BIG_ENDIAN 2377 if (!info->kms_enabled) { 2378 /* restore byte swapping */ 2379 OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl); 2380 } 2381#endif 2382 } 2383} 2384 2385 2386#ifdef XF86DRI 2387static void RADEON_420_422( 2388 unsigned int *d, 2389 unsigned char *s1, 2390 unsigned char *s2, 2391 unsigned char *s3, 2392 unsigned int n 2393) 2394{ 2395 while ( n ) { 2396 *(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); 2397 s1+=2; s2++; s3++; 2398 n--; 2399 } 2400} 2401#endif 2402 2403void 2404RADEONCopyMungedData( 2405 ScrnInfoPtr pScrn, 2406 unsigned char *src1, 2407 unsigned char *src2, 2408 unsigned char *src3, 2409 unsigned char *dst1, 2410 unsigned int srcPitch, 2411 unsigned int srcPitch2, 2412 unsigned int dstPitch, 2413 unsigned int h, 2414 unsigned int w 2415){ 2416 RADEONInfoPtr info = RADEONPTR(pScrn); 2417#ifdef XF86DRI 2418 2419 if ( info->directRenderingEnabled && info->DMAForXv ) 2420 { 2421 uint8_t *buf; 2422 uint32_t y = 0, bufPitch, dstPitchOff; 2423 int blitX, blitY; 2424 unsigned int hpass; 2425 2426 /* XXX Fix endian flip on R300 */ 2427 2428 RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY ); 2429 2430 while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch, 2431 blitX, &blitY, &h, &hpass )) ) 2432 { 2433 while ( hpass-- ) 2434 { 2435 RADEON_420_422( (unsigned int *) buf, src1, src2, src3, 2436 bufPitch / 4 ); 2437 src1 += srcPitch; 2438 if ( y & 1 ) 2439 { 2440 src2 += srcPitch2; 2441 src3 += srcPitch2; 2442 } 2443 buf += bufPitch; 2444 y++; 2445 } 2446 } 2447 2448 FLUSH_RING(); 2449 } 2450 else 2451#endif /* XF86DRI */ 2452 { 2453 uint32_t *dst; 2454 uint8_t *s1, *s2, *s3; 2455 int i, j; 2456 2457#if X_BYTE_ORDER == X_BIG_ENDIAN 2458 unsigned char *RADEONMMIO = info->MMIO; 2459 2460 if (!info->kms_enabled) 2461 OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl & 2462 ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP0_SWP_32BPP)); 2463#endif 2464 2465 w /= 2; 2466 2467 for( j = 0; j < h; j++ ) 2468 { 2469 dst = (pointer)dst1; 2470 s1 = src1; s2 = src2; s3 = src3; 2471 i = w; 2472 while( i > 4 ) 2473 { 2474 dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24)); 2475 dst[1] = cpu_to_le32(s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24)); 2476 dst[2] = cpu_to_le32(s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24)); 2477 dst[3] = cpu_to_le32(s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24)); 2478 dst += 4; s2 += 4; s3 += 4; s1 += 8; 2479 i -= 4; 2480 } 2481 while( i-- ) 2482 { 2483 dst[0] = cpu_to_le32(s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24)); 2484 dst++; s2++; s3++; 2485 s1 += 2; 2486 } 2487 2488 dst1 += dstPitch; 2489 src1 += srcPitch; 2490 if( j & 1 ) 2491 { 2492 src2 += srcPitch2; 2493 src3 += srcPitch2; 2494 } 2495 } 2496#if X_BYTE_ORDER == X_BIG_ENDIAN 2497 if (!info->kms_enabled) { 2498 /* restore byte swapping */ 2499 OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl); 2500 } 2501#endif 2502 } 2503} 2504 2505static void 2506RADEONDisplayVideo( 2507 ScrnInfoPtr pScrn, 2508 xf86CrtcPtr crtc, 2509 RADEONPortPrivPtr pPriv, 2510 int id, 2511 int base_offset, 2512 int offset1, int offset2, 2513 int offset3, int offset4, 2514 int offset5, int offset6, 2515 short width, short height, 2516 int pitch, 2517 int left, int right, int top, 2518 BoxPtr dstBox, 2519 short src_w, short src_h, 2520 short drw_w, short drw_h, 2521 int deinterlacing_method 2522){ 2523 RADEONInfoPtr info = RADEONPTR(pScrn); 2524 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2525 unsigned char *RADEONMMIO = info->MMIO; 2526 uint32_t v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp; 2527 double h_inc_d; 2528 int p1_h_accum_init, p23_h_accum_init; 2529 int p1_v_accum_init, p23_v_accum_init; 2530 int p23_blank_lines; 2531 int ecp_div; 2532 int v_inc_shift; 2533 int y_mult; 2534 int x_off; 2535 int y_off; 2536 uint32_t scaler_src; 2537 uint32_t dot_clock; 2538 int is_rgb; 2539 int is_planar; 2540 int i; 2541 uint32_t scale_cntl; 2542 double dsr; 2543 int tap_set; 2544 int predownscale=0; 2545 int src_w_d; 2546 int leftuv = 0; 2547 DisplayModePtr mode; 2548 RADEONOutputPrivatePtr radeon_output; 2549 xf86OutputPtr output; 2550 RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; 2551 2552 is_rgb=0; is_planar=0; 2553 switch(id){ 2554 case FOURCC_I420: 2555 case FOURCC_YV12: 2556 is_planar=1; 2557 break; 2558 case FOURCC_RGBA32: 2559 case FOURCC_RGB24: 2560 case FOURCC_RGBT16: 2561 case FOURCC_RGB16: 2562 is_rgb=1; 2563 break; 2564 default: 2565 break; 2566 } 2567 2568 /* Here we need to find ecp_div again, as the user may have switched resolutions 2569 but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to 2570 workarounds for chip erratas */ 2571 2572 /* Figure out which head we are on for dot clock */ 2573 if (radeon_crtc->crtc_id == 1) 2574 dot_clock = info->ModeReg->dot_clock_freq_2; 2575 else 2576 dot_clock = info->ModeReg->dot_clock_freq; 2577 2578 if (dot_clock < 17500) 2579 ecp_div = 0; 2580 else 2581 ecp_div = 1; 2582 2583 if (ecp_div != info->ecp_div) { 2584 info->ecp_div = ecp_div; 2585 OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, 2586 (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8)); 2587 } 2588 2589 /* I suspect we may need a usleep after writing to the PLL. if you play a video too soon 2590 after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey 2591 on the right edge video output. 2592 Is this still the case? Might have been chips which need the errata, 2593 there is now plenty of usleep after INPLL/OUTPLL for those...*/ 2594 2595 v_inc_shift = 20; 2596 y_mult = 1; 2597 2598 mode = &crtc->mode; 2599 2600 if (mode->Flags & V_INTERLACE) 2601 v_inc_shift++; 2602 if (mode->Flags & V_DBLSCAN) { 2603 v_inc_shift--; 2604 y_mult = 2; 2605 } 2606 2607 v_inc = (src_h << v_inc_shift) / drw_h; 2608 2609 for (i = 0; i < xf86_config->num_output; i++) { 2610 output = xf86_config->output[i]; 2611 if (output->crtc == crtc) { 2612 radeon_output = output->driver_private; 2613 if (radeon_output->Flags & RADEON_USE_RMX) 2614 v_inc = ((src_h * mode->CrtcVDisplay / 2615 radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h; 2616 break; 2617 } 2618 } 2619 2620 h_inc = (1 << (12 + ecp_div)); 2621 2622 step_by_y = 1; 2623 step_by_uv = step_by_y; 2624 2625 src_w_d = src_w; 2626#if 0 2627 /* XXX this does not appear to work */ 2628 /* if the source width was larger than what would fit in overlay scaler increase step_by values */ 2629 i=src_w; 2630 while(i>info->overlay_scaler_buffer_width){ 2631 step_by_y++; 2632 step_by_uv++; 2633 h_inc >>=1; 2634 i=i/2; 2635 } 2636#else 2637 /* predownscale instead (yes this hurts quality) - will only work for widths up 2638 to 2 times the overlay_scaler_buffer_width, should be enough */ 2639 if (src_w_d > info->overlay_scaler_buffer_width) { 2640 src_w_d /= 2; /* odd widths? */ 2641 predownscale = 1; 2642 } 2643#endif 2644 2645 h_inc_d = src_w_d; 2646 h_inc_d = h_inc_d/drw_w; 2647 /* we could do a tad better - but why 2648 bother when this concerns downscaling and the code is so much more 2649 hairy */ 2650 while(h_inc*h_inc_d >= (2 << 12)) { 2651 if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){ 2652 step_by_uv = step_by_y+1; 2653 break; 2654 } 2655 step_by_y++; 2656 step_by_uv = step_by_y; 2657 h_inc >>= 1; 2658 } 2659 2660 h_inc_uv = h_inc>>(step_by_uv-step_by_y); 2661 h_inc = h_inc * h_inc_d; 2662 h_inc_uv = h_inc_uv * h_inc_d; 2663 /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit 2664 in the buffer for 2 tap filtering */ 2665 /* the only place it is documented in is in ATI source code */ 2666 /* we need twice as much space for 4 tap filtering.. */ 2667 /* under special circumstances turn on 4 tap filtering */ 2668 /* disable this code for now as it has a DISASTROUS effect on image quality when upscaling 2669 at least on rv250 (only as long as the drw_w*2 <=... requirement is still met of course) */ 2670#if 0 2671 if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12)) 2672 && (deinterlacing_method!=METHOD_WEAVE) 2673 && (drw_w*2 <= info->overlay_scaler_buffer_width)){ 2674 step_by_y=0; 2675 step_by_uv=1; 2676 h_inc_uv = h_inc; 2677 } 2678#endif 2679 2680 /* Make the overlay base address as close to the buffers as possible to 2681 * prevent the buffer offsets from exceeding the hardware limit of 128 MB. 2682 * The base address must be aligned to a multiple of 4 MB. 2683 */ 2684 base_offset = ((info->fbLocation + base_offset) & (~0 << 22)) - 2685 info->fbLocation; 2686 2687 offset1 -= base_offset; 2688 offset2 -= base_offset; 2689 offset3 -= base_offset; 2690 offset4 -= base_offset; 2691 offset5 -= base_offset; 2692 offset6 -= base_offset; 2693 2694 /* keep everything in 16.16 */ 2695 2696 if (is_planar) { 2697 offset1 += ((left >> 16) & ~15); 2698 offset2 += ((left >> 16) & ~31) >> 1; 2699 offset3 += ((left >> 16) & ~31) >> 1; 2700 offset4 += ((left >> 16) & ~15); 2701 offset5 += ((left >> 16) & ~31) >> 1; 2702 offset6 += ((left >> 16) & ~31) >> 1; 2703 offset2 |= RADEON_VIF_BUF0_PITCH_SEL; 2704 offset3 |= RADEON_VIF_BUF0_PITCH_SEL; 2705 offset5 |= RADEON_VIF_BUF0_PITCH_SEL; 2706 offset6 |= RADEON_VIF_BUF0_PITCH_SEL; 2707 } 2708 else { 2709 /* is this really correct for non-2-byte formats? */ 2710 offset1 += ((left >> 16) & ~7) << 1; 2711 offset2 += ((left >> 16) & ~7) << 1; 2712 offset3 += ((left >> 16) & ~7) << 1; 2713 offset4 += ((left >> 16) & ~7) << 1; 2714 offset5 += ((left >> 16) & ~7) << 1; 2715 offset6 += ((left >> 16) & ~7) << 1; 2716 } 2717 2718 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); 2719 p1_h_accum_init = ((tmp << 4) & 0x000f8000) | 2720 ((tmp << 12) & 0xf0000000); 2721 2722 tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2); 2723 p23_h_accum_init = ((tmp << 4) & 0x000f8000) | 2724 ((tmp << 12) & 0x70000000); 2725 2726 tmp = (top & 0x0000ffff) + 0x00018000; 2727 p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 2728 (((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01); 2729 2730 if (is_planar) { 2731 p23_v_accum_init = ((tmp << 4) & 0x03ff8000) | 2732 ((deinterlacing_method != METHOD_WEAVE) ? 0x03 : 0x01); 2733 p23_blank_lines = (((src_h >> 1) - 1) << 16); 2734 } 2735 else { 2736 p23_v_accum_init = 0; 2737 p23_blank_lines = 0; 2738 } 2739 2740 if (is_planar) { 2741 leftuv = ((left >> 16) >> 1) & 15; 2742 left = (left >> 16) & 15; 2743 } 2744 else { 2745 left = (left >> 16) & 7; 2746 if (!is_rgb) 2747 leftuv = left >> 1; 2748 } 2749 2750 RADEONWaitForFifo(pScrn, 2); 2751 OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK); 2752 if (info->accelOn) RADEON_SYNC(info, pScrn); 2753 while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK)); 2754 2755 RADEONWaitForFifo(pScrn, 10); 2756 OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16)); 2757 OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) | 2758 predownscale << 4 | predownscale << 12); 2759 2760 x_off = 8; 2761 y_off = 0; 2762 2763 if (IS_R300_VARIANT || 2764 (info->ChipFamily == CHIP_FAMILY_R200)) 2765 x_off = 0; 2766 2767 /* needed to make the overlay work on crtc1 in leftof and above modes */ 2768 /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */ 2769 /* 2770 if (srel == radeonLeftOf) { 2771 x_off -= mode->CrtcHDisplay; 2772 } 2773 if (srel == radeonAbove) { 2774 y_off -= mode->CrtcVDisplay; 2775 } 2776 */ 2777 2778 /* Put the hardware overlay on CRTC2: 2779 * 2780 * Since one hardware overlay can not be displayed on two heads 2781 * at the same time, we might need to consider using software 2782 * rendering for the second head. 2783 */ 2784 2785 if (radeon_crtc->crtc_id == 1) { 2786 x_off = 0; 2787 OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) | 2788 ((dstBox->y1*y_mult) << 16))); 2789 OUTREG(RADEON_OV1_Y_X_END, ((dstBox->x2 + x_off) | 2790 ((dstBox->y2*y_mult) << 16))); 2791 scaler_src = RADEON_SCALER_CRTC_SEL; 2792 } else { 2793 OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) | 2794 (((dstBox->y1*y_mult) + y_off) << 16))); 2795 OUTREG(RADEON_OV0_Y_X_END, ((dstBox->x2 + x_off) | 2796 (((dstBox->y2*y_mult) + y_off) << 16))); 2797 scaler_src = 0; 2798 } 2799 2800 /* program the tap coefficients for better downscaling quality. 2801 Could do slightly better by using hardcoded coefficients for one axis 2802 in case only the other axis is downscaled (see RADEON_OV0_FILTER_CNTL) */ 2803 dsr=(double)(1<<0xC)/h_inc; 2804 if(dsr<0.25)dsr=0.25; 2805 if(dsr>1.0)dsr=1.0; 2806 tap_set=(int)((dsr-0.25)*100); 2807 for(i=0;i<5;i++){ 2808 OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) | 2809 ((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) | 2810 ((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) | 2811 ((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24)); 2812 } 2813 2814 RADEONWaitForFifo(pScrn, 11); 2815 OUTREG(RADEON_OV0_V_INC, v_inc); 2816 OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16)); 2817 OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | p23_blank_lines); 2818 OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch); 2819 OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch); 2820 OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16)); 2821 if (!is_rgb) 2822 src_w >>= 1; 2823 OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16)); 2824 OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16)); 2825 if (info->ModeReg->ov0_base_addr != (info->fbLocation + base_offset)) { 2826 ErrorF("Changing OV0_BASE_ADDR from 0x%08x to 0x%08x\n", 2827 info->ModeReg->ov0_base_addr, (uint32_t)info->fbLocation + base_offset); 2828 info->ModeReg->ov0_base_addr = info->fbLocation + base_offset; 2829 OUTREG(RADEON_OV0_BASE_ADDR, info->ModeReg->ov0_base_addr); 2830 } 2831 OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1); 2832 OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2); 2833 OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3); 2834 2835 RADEONWaitForFifo(pScrn, 9); 2836 OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4); 2837 OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset5); 2838 OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset6); 2839 OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init); 2840 OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init); 2841 OUTREG(RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init); 2842 OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init); 2843 2844 scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER 2845 | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16) | scaler_src; 2846 switch(id){ 2847 case FOURCC_UYVY: 2848 scale_cntl |= RADEON_SCALER_SOURCE_YVYU422; 2849 break; 2850 case FOURCC_RGB24: 2851 case FOURCC_RGBA32: 2852 scale_cntl |= RADEON_SCALER_SOURCE_32BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2853 break; 2854 case FOURCC_RGB16: 2855 scale_cntl |= RADEON_SCALER_SOURCE_16BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2856 break; 2857 case FOURCC_RGBT16: 2858 scale_cntl |= RADEON_SCALER_SOURCE_15BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2859 break; 2860 case FOURCC_YV12: 2861 case FOURCC_I420: 2862 scale_cntl |= RADEON_SCALER_SOURCE_YUV12; 2863 break; 2864 case FOURCC_YUY2: 2865 default: 2866 scale_cntl |= RADEON_SCALER_SOURCE_VYUY422 2867 | ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0); 2868 break; 2869 } 2870 2871 if (info->ChipFamily < CHIP_FAMILY_R200) { 2872 scale_cntl &= ~RADEON_SCALER_GAMMA_SEL_MASK; 2873 scale_cntl |= ((RADEONTranslateUserGamma(pPriv->gamma)) << 5); 2874 } 2875 2876 OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl); 2877 OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0); 2878} 2879 2880 2881static void 2882RADEONFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes) 2883{ 2884#if HAVE_XV_DRAWABLE_HELPER 2885 xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes); 2886#else 2887 xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes); 2888#endif 2889} 2890 2891 2892static int 2893RADEONPutImage( 2894 ScrnInfoPtr pScrn, 2895 short src_x, short src_y, 2896 short drw_x, short drw_y, 2897 short src_w, short src_h, 2898 short drw_w, short drw_h, 2899 int id, unsigned char* buf, 2900 short width, short height, 2901 Bool Sync, 2902 RegionPtr clipBoxes, pointer data, 2903 DrawablePtr pDraw 2904){ 2905 RADEONInfoPtr info = RADEONPTR(pScrn); 2906 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 2907 INT32 xa, xb, ya, yb; 2908 unsigned char *dst_start; 2909 int new_size, offset, s2offset, s3offset; 2910 int srcPitch, srcPitch2, dstPitch; 2911 int d2line, d3line; 2912 int top, left, npixels, nlines, bpp; 2913 int idconv = id; 2914 BoxRec dstBox; 2915 uint32_t tmp; 2916 xf86CrtcPtr crtc; 2917 2918 /* 2919 * s2offset, s3offset - byte offsets into U and V plane of the 2920 * source where copying starts. Y plane is 2921 * done by editing "buf". 2922 * 2923 * offset - byte offset to the first line of the destination. 2924 * 2925 * dst_start - byte address to the first displayed pel. 2926 * 2927 */ 2928 2929 /* make the compiler happy */ 2930 s2offset = s3offset = srcPitch2 = 0; 2931 d2line = d3line = 0; 2932 2933 if(src_w > (drw_w << 4)) 2934 drw_w = src_w >> 4; 2935 if(src_h > (drw_h << 4)) 2936 drw_h = src_h >> 4; 2937 2938 /* Clip */ 2939 xa = src_x; 2940 xb = src_x + src_w; 2941 ya = src_y; 2942 yb = src_y + src_h; 2943 2944 dstBox.x1 = drw_x; 2945 dstBox.x2 = drw_x + drw_w; 2946 dstBox.y1 = drw_y; 2947 dstBox.y2 = drw_y + drw_h; 2948 2949 if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc, 2950 &dstBox, &xa, &xb, &ya, &yb, 2951 clipBoxes, width, height)) 2952 return Success; 2953 2954 if (!crtc) { 2955 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 2956 unsigned char *RADEONMMIO = info->MMIO; 2957 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 2958 pPriv->videoStatus &= ~CLIENT_VIDEO_ON; 2959 } 2960 return Success; 2961 } 2962 2963 dstBox.x1 -= crtc->x; 2964 dstBox.x2 -= crtc->x; 2965 dstBox.y1 -= crtc->y; 2966 dstBox.y2 -= crtc->y; 2967 2968 bpp = pScrn->bitsPerPixel >> 3; 2969 2970 switch(id) { 2971 case FOURCC_RGB24: 2972 dstPitch = width * 4; 2973 srcPitch = width * 3; 2974 break; 2975 case FOURCC_RGBA32: 2976 dstPitch = width * 4; 2977 srcPitch = width * 4; 2978 break; 2979 case FOURCC_RGB16: 2980 case FOURCC_RGBT16: 2981 dstPitch = width * 2; 2982 srcPitch = RADEON_ALIGN(width * 2, 4); 2983 break; 2984 case FOURCC_YV12: 2985 case FOURCC_I420: 2986 /* it seems rs4xx chips (all of them???) either can't handle planar 2987 yuv at all or would need some unknown different setup. */ 2988 if ((info->ChipFamily != CHIP_FAMILY_RS400) && 2989 (info->ChipFamily != CHIP_FAMILY_RS480)) { 2990 /* need 16bytes alignment for u,v plane, so 2 times that for width 2991 but blitter needs 64bytes alignment. 128byte is a waste but dstpitch 2992 for uv planes needs to be dstpitch yplane >> 1 for now. */ 2993 dstPitch = (RADEON_ALIGN(width, 128)); 2994 srcPitch = RADEON_ALIGN(width, 4); 2995 } 2996 else { 2997 dstPitch = width * 2; 2998 srcPitch = RADEON_ALIGN(width, 4); 2999 idconv = FOURCC_YUY2; 3000 } 3001 break; 3002 case FOURCC_UYVY: 3003 case FOURCC_YUY2: 3004 default: 3005 dstPitch = width * 2; 3006 srcPitch = width * 2; 3007 break; 3008 } 3009 3010#ifdef XF86DRI 3011 if (info->directRenderingEnabled && info->DMAForXv) { 3012 /* The upload blit only supports multiples of 64 bytes */ 3013 dstPitch = RADEON_ALIGN(dstPitch, 64); 3014 } else 3015#endif 3016 /* The overlay only supports multiples of 16 bytes */ 3017 dstPitch = RADEON_ALIGN(dstPitch, 16); 3018 3019 new_size = dstPitch * height; 3020 if (idconv == FOURCC_YV12 || id == FOURCC_I420) { 3021 new_size += (dstPitch >> 1) * (RADEON_ALIGN(height, 2)); 3022 } 3023 pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory, 3024 (pPriv->doubleBuffer ? 3025 (new_size * 2) : new_size), 64, 3026 RADEON_GEM_DOMAIN_VRAM); 3027 if (pPriv->video_offset == 0) 3028 return BadAlloc; 3029 3030 pPriv->currentBuffer ^= 1; 3031 3032 /* copy data */ 3033 top = ya >> 16; 3034 left = (xa >> 16) & ~1; 3035 npixels = ((xb + 0xffff) >> 16) - left; 3036 3037 offset = (pPriv->video_offset) + (top * dstPitch); 3038 3039 if(pPriv->doubleBuffer) { 3040 unsigned char *RADEONMMIO = info->MMIO; 3041 3042 /* Wait for last flip to take effect */ 3043 while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK)); 3044 3045 offset += pPriv->currentBuffer * new_size; 3046 } 3047 3048 dst_start = info->FB + offset; 3049 3050 switch(id) { 3051 case FOURCC_YV12: 3052 case FOURCC_I420: 3053 if (id == idconv) { 3054 /* meh. Such a mess just for someone who wants to watch half the video clipped */ 3055 top &= ~1; 3056 /* odd number of pixels? That may not work correctly */ 3057 srcPitch2 = RADEON_ALIGN(width >> 1, 4); 3058 /* odd number of lines? Maybe... */ 3059 s2offset = srcPitch * (RADEON_ALIGN(height, 2)); 3060 s3offset = s2offset + srcPitch2 * ((height + 1) >> 1); 3061 s2offset += (top >> 1) * srcPitch2 + (left >> 1); 3062 s3offset += (top >> 1) * srcPitch2 + (left >> 1); 3063 d2line = (height * dstPitch); 3064 d3line = d2line + ((height + 1) >> 1) * (dstPitch >> 1); 3065 nlines = ((yb + 0xffff) >> 16) - top; 3066 d2line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch); 3067 d3line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch); 3068 if(id == FOURCC_YV12) { 3069 tmp = s2offset; 3070 s2offset = s3offset; 3071 s3offset = tmp; 3072 } 3073 RADEONCopyData(pScrn, buf + (top * srcPitch) + left, dst_start + left, 3074 srcPitch, dstPitch, nlines, npixels, 1); 3075 RADEONCopyData(pScrn, buf + s2offset, dst_start + d2line + (left >> 1), 3076 srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1); 3077 RADEONCopyData(pScrn, buf + s3offset, dst_start + d3line + (left >> 1), 3078 srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1); 3079 } 3080 else { 3081 s2offset = srcPitch * height; 3082 srcPitch2 = RADEON_ALIGN(width >> 1, 4); 3083 s3offset = (srcPitch2 * (height >> 1)) + s2offset; 3084 top &= ~1; 3085 dst_start += left << 1; 3086 tmp = ((top >> 1) * srcPitch2) + (left >> 1); 3087 s2offset += tmp; 3088 s3offset += tmp; 3089 if(id == FOURCC_I420) { 3090 tmp = s2offset; 3091 s2offset = s3offset; 3092 s3offset = tmp; 3093 } 3094 nlines = ((yb + 0xffff) >> 16) - top; 3095 RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left, 3096 buf + s2offset, buf + s3offset, dst_start, 3097 srcPitch, srcPitch2, dstPitch, nlines, npixels); 3098 } 3099 break; 3100 case FOURCC_RGBT16: 3101 case FOURCC_RGB16: 3102 case FOURCC_UYVY: 3103 case FOURCC_YUY2: 3104 default: 3105 left <<= 1; 3106 buf += (top * srcPitch) + left; 3107 nlines = ((yb + 0xffff) >> 16) - top; 3108 dst_start += left; 3109 RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2); 3110 break; 3111 case FOURCC_RGBA32: 3112 buf += (top * srcPitch) + left*4; 3113 nlines = ((yb + 0xffff) >> 16) - top; 3114 dst_start += left*4; 3115 RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4); 3116 break; 3117 case FOURCC_RGB24: 3118 buf += (top * srcPitch) + left*3; 3119 nlines = ((yb + 0xffff) >> 16) - top; 3120 dst_start += left*4; 3121 RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels); 3122 break; 3123 } 3124 3125 /* update cliplist */ 3126 if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) 3127 { 3128 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 3129 /* draw these */ 3130 if(pPriv->autopaint_colorkey) 3131 RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 3132 } 3133 3134 /* FIXME: someone should look at these offsets, I don't think it makes sense how 3135 they are handled throughout the source. */ 3136 RADEONDisplayVideo(pScrn, crtc, pPriv, idconv, pPriv->video_offset, offset, 3137 offset + d2line, offset + d3line, offset, offset + d2line, 3138 offset + d3line, width, height, dstPitch, xa, xb, ya, 3139 &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB); 3140 3141 pPriv->videoStatus = CLIENT_VIDEO_ON; 3142 3143 info->VideoTimerCallback = RADEONVideoTimerCallback; 3144 3145 return Success; 3146} 3147 3148 3149int 3150RADEONQueryImageAttributes( 3151 ScrnInfoPtr pScrn, 3152 int id, 3153 unsigned short *w, unsigned short *h, 3154 int *pitches, int *offsets 3155){ 3156 const RADEONInfoRec * const info = RADEONPTR(pScrn); 3157 int size, tmp; 3158 3159 if(*w > info->xv_max_width) *w = info->xv_max_width; 3160 if(*h > info->xv_max_height) *h = info->xv_max_height; 3161 3162 *w = RADEON_ALIGN(*w, 2); 3163 if(offsets) offsets[0] = 0; 3164 3165 switch(id) { 3166 case FOURCC_YV12: 3167 case FOURCC_I420: 3168 *h = RADEON_ALIGN(*h, 2); 3169 size = RADEON_ALIGN(*w, 4); 3170 if(pitches) pitches[0] = size; 3171 size *= *h; 3172 if(offsets) offsets[1] = size; 3173 tmp = RADEON_ALIGN(*w >> 1, 4); 3174 if(pitches) pitches[1] = pitches[2] = tmp; 3175 tmp *= (*h >> 1); 3176 size += tmp; 3177 if(offsets) offsets[2] = size; 3178 size += tmp; 3179 break; 3180 case FOURCC_RGBA32: 3181 size = *w << 2; 3182 if(pitches) pitches[0] = size; 3183 size *= *h; 3184 break; 3185 case FOURCC_RGB24: 3186 size = *w * 3; 3187 if(pitches) pitches[0] = size; 3188 size *= *h; 3189 break; 3190 case FOURCC_RGBT16: 3191 case FOURCC_RGB16: 3192 case FOURCC_UYVY: 3193 case FOURCC_YUY2: 3194 default: 3195 size = *w << 1; 3196 if(pitches) pitches[0] = size; 3197 size *= *h; 3198 break; 3199 } 3200 3201 return size; 3202} 3203 3204static void 3205RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now) 3206{ 3207 RADEONInfoPtr info = RADEONPTR(pScrn); 3208 RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; 3209 3210 if(pPriv->videoStatus & TIMER_MASK) { 3211 if(pPriv->videoStatus & OFF_TIMER) { 3212 if(pPriv->offTime < now) { 3213 unsigned char *RADEONMMIO = info->MMIO; 3214 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3215 pPriv->videoStatus = FREE_TIMER; 3216 pPriv->freeTime = now + FREE_DELAY; 3217 } 3218 } else { /* FREE_TIMER */ 3219 if(pPriv->freeTime < now) { 3220 RADEONFreeVideoMemory(pScrn, pPriv); 3221 pPriv->videoStatus = 0; 3222 info->VideoTimerCallback = NULL; 3223 } 3224 } 3225 } else /* shouldn't get here */ 3226 info->VideoTimerCallback = NULL; 3227} 3228 3229/****************** Offscreen stuff ***************/ 3230typedef struct { 3231 void *surface_memory; 3232 Bool isOn; 3233} OffscreenPrivRec, * OffscreenPrivPtr; 3234 3235static int 3236RADEONAllocateSurface( 3237 ScrnInfoPtr pScrn, 3238 int id, 3239 unsigned short w, 3240 unsigned short h, 3241 XF86SurfacePtr surface 3242){ 3243 int offset, pitch, size; 3244 OffscreenPrivPtr pPriv; 3245 void *surface_memory = NULL; 3246 if((w > 1024) || (h > 1024)) 3247 return BadAlloc; 3248 3249 w = RADEON_ALIGN(w, 2); 3250 pitch = RADEON_ALIGN(w << 1, 16); 3251 size = pitch * h; 3252 3253 offset = radeon_legacy_allocate_memory(pScrn, &surface_memory, size, 64, 3254 RADEON_GEM_DOMAIN_VRAM); 3255 if (offset == 0) 3256 return BadAlloc; 3257 3258 surface->width = w; 3259 surface->height = h; 3260 3261 if(!(surface->pitches = malloc(sizeof(int)))) { 3262 radeon_legacy_free_memory(pScrn, surface_memory); 3263 return BadAlloc; 3264 } 3265 if(!(surface->offsets = malloc(sizeof(int)))) { 3266 free(surface->pitches); 3267 radeon_legacy_free_memory(pScrn, surface_memory); 3268 return BadAlloc; 3269 } 3270 if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 3271 free(surface->pitches); 3272 free(surface->offsets); 3273 radeon_legacy_free_memory(pScrn, surface_memory); 3274 return BadAlloc; 3275 } 3276 3277 pPriv->surface_memory = surface_memory; 3278 pPriv->isOn = FALSE; 3279 3280 surface->pScrn = pScrn; 3281 surface->id = id; 3282 surface->pitches[0] = pitch; 3283 surface->offsets[0] = offset; 3284 surface->devPrivate.ptr = (pointer)pPriv; 3285 3286 return Success; 3287} 3288 3289static int 3290RADEONStopSurface( 3291 XF86SurfacePtr surface 3292){ 3293 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3294 RADEONInfoPtr info = RADEONPTR(surface->pScrn); 3295 unsigned char *RADEONMMIO = info->MMIO; 3296 3297 if(pPriv->isOn) { 3298 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3299 pPriv->isOn = FALSE; 3300 } 3301 return Success; 3302} 3303 3304 3305static int 3306RADEONFreeSurface( 3307 XF86SurfacePtr surface 3308){ 3309 ScrnInfoPtr pScrn = surface->pScrn; 3310 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3311 3312 if(pPriv->isOn) 3313 RADEONStopSurface(surface); 3314 radeon_legacy_free_memory(pScrn, pPriv->surface_memory); 3315 pPriv->surface_memory = NULL; 3316 free(surface->pitches); 3317 free(surface->offsets); 3318 free(surface->devPrivate.ptr); 3319 3320 return Success; 3321} 3322 3323static int 3324RADEONGetSurfaceAttribute( 3325 ScrnInfoPtr pScrn, 3326 Atom attribute, 3327 INT32 *value 3328){ 3329 return RADEONGetPortAttribute(pScrn, attribute, value, 3330 (pointer)(GET_PORT_PRIVATE(pScrn))); 3331} 3332 3333static int 3334RADEONSetSurfaceAttribute( 3335 ScrnInfoPtr pScrn, 3336 Atom attribute, 3337 INT32 value 3338){ 3339 return RADEONSetPortAttribute(pScrn, attribute, value, 3340 (pointer)(GET_PORT_PRIVATE(pScrn))); 3341} 3342 3343 3344static int 3345RADEONDisplaySurface( 3346 XF86SurfacePtr surface, 3347 short src_x, short src_y, 3348 short drw_x, short drw_y, 3349 short src_w, short src_h, 3350 short drw_w, short drw_h, 3351 RegionPtr clipBoxes 3352){ 3353 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3354 ScrnInfoPtr pScrn = surface->pScrn; 3355 RADEONInfoPtr info = RADEONPTR(pScrn); 3356 RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr; 3357 3358 INT32 xa, ya, xb, yb; 3359 BoxRec dstBox; 3360 xf86CrtcPtr crtc; 3361 3362 if (src_w > (drw_w << 4)) 3363 drw_w = src_w >> 4; 3364 if (src_h > (drw_h << 4)) 3365 drw_h = src_h >> 4; 3366 3367 xa = src_x; 3368 xb = src_x + src_w; 3369 ya = src_y; 3370 yb = src_y + src_h; 3371 3372 dstBox.x1 = drw_x; 3373 dstBox.x2 = drw_x + drw_w; 3374 dstBox.y1 = drw_y; 3375 dstBox.y2 = drw_y + drw_h; 3376 3377 if (!radeon_crtc_clip_video(pScrn, &crtc, portPriv->desired_crtc, 3378 &dstBox, &xa, &xb, &ya, &yb, clipBoxes, 3379 surface->width, surface->height)) 3380 return Success; 3381 3382 if (!crtc) { 3383 if (pPriv->isOn) { 3384 unsigned char *RADEONMMIO = info->MMIO; 3385 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3386 pPriv->isOn = FALSE; 3387 } 3388 return Success; 3389 } 3390 3391 dstBox.x1 -= crtc->x; 3392 dstBox.x2 -= crtc->x; 3393 dstBox.y1 -= crtc->y; 3394 dstBox.y2 -= crtc->y; 3395 3396#if 0 3397 /* this isn't needed */ 3398 RADEONResetVideo(pScrn); 3399#endif 3400 RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id, 3401 surface->offsets[0], surface->offsets[0], 3402 surface->offsets[0], surface->offsets[0], 3403 surface->offsets[0], surface->offsets[0], 3404 surface->offsets[0], surface->width, surface->height, 3405 surface->pitches[0], xa, xb, ya, &dstBox, src_w, src_h, 3406 drw_w, drw_h, METHOD_BOB); 3407 3408 if (portPriv->autopaint_colorkey) 3409 xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 3410 3411 pPriv->isOn = TRUE; 3412 /* we've prempted the XvImage stream so set its free timer */ 3413 if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 3414 REGION_EMPTY(pScrn->pScreen, &portPriv->clip); 3415 UpdateCurrentTime(); 3416 portPriv->videoStatus = FREE_TIMER; 3417 portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 3418 info->VideoTimerCallback = RADEONVideoTimerCallback; 3419 } 3420 3421 return Success; 3422} 3423 3424 3425static void 3426RADEONInitOffscreenImages(ScreenPtr pScreen) 3427{ 3428/* ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 3429 RADEONInfoPtr info = RADEONPTR(pScrn); */ 3430 XF86OffscreenImagePtr offscreenImages; 3431 /* need to free this someplace */ 3432 3433 if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 3434 return; 3435 3436 offscreenImages[0].image = &Images[0]; 3437 offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*| 3438 VIDEO_CLIP_TO_VIEWPORT*/; 3439 offscreenImages[0].alloc_surface = RADEONAllocateSurface; 3440 offscreenImages[0].free_surface = RADEONFreeSurface; 3441 offscreenImages[0].display = RADEONDisplaySurface; 3442 offscreenImages[0].stop = RADEONStopSurface; 3443 offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute; 3444 offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute; 3445 offscreenImages[0].max_width = 2047; 3446 offscreenImages[0].max_height = 2047; 3447 offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 3448 offscreenImages[0].attributes = Attributes; 3449 3450 xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 3451} 3452 3453 /* TV-in functions */ 3454 3455static int 3456RADEONPutVideo( 3457 ScrnInfoPtr pScrn, 3458 short src_x, short src_y, 3459 short drw_x, short drw_y, 3460 short src_w, short src_h, 3461 short drw_w, short drw_h, 3462 RegionPtr clipBoxes, pointer data, 3463 DrawablePtr pDraw 3464){ 3465 RADEONInfoPtr info = RADEONPTR(pScrn); 3466 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 3467 unsigned char *RADEONMMIO = info->MMIO; 3468 INT32 xa, xb, ya, yb, top; 3469 unsigned int pitch, new_size, alloc_size; 3470 unsigned int offset1, offset2, offset3, offset4, s2offset, s3offset; 3471 unsigned int vbi_offset0, vbi_offset1; 3472 int srcPitch, srcPitch2, dstPitch; 3473 int bpp; 3474 BoxRec dstBox; 3475 uint32_t id, display_base; 3476 int width, height; 3477 int mult; 3478 int vbi_line_width, vbi_start, vbi_end; 3479 xf86CrtcPtr crtc; 3480 3481 RADEON_SYNC(info, pScrn); 3482 /* 3483 * s2offset, s3offset - byte offsets into U and V plane of the 3484 * source where copying starts. Y plane is 3485 * done by editing "buf". 3486 * 3487 * offset - byte offset to the first line of the destination. 3488 * 3489 * dst_start - byte address to the first displayed pel. 3490 * 3491 */ 3492 3493 /* make the compiler happy */ 3494 s2offset = s3offset = srcPitch2 = 0; 3495 3496 if(src_w > (drw_w << 4)) 3497 drw_w = src_w >> 4; 3498 if(src_h > (drw_h << 4)) 3499 drw_h = src_h >> 4; 3500 3501 /* Clip */ 3502 xa = src_x; 3503 xb = src_x + src_w; 3504 ya = src_y; 3505 yb = src_y + src_h; 3506 3507 dstBox.x1 = drw_x; 3508 dstBox.x2 = drw_x + drw_w; 3509 dstBox.y1 = drw_y; 3510 dstBox.y2 = drw_y + drw_h; 3511 3512 width = InputVideoEncodings[pPriv->encoding].width; 3513 height = InputVideoEncodings[pPriv->encoding].height; 3514 3515 vbi_line_width = 798*2; 3516 if(width<=640) 3517 vbi_line_width = 0x640; /* 1600 actually */ 3518 else 3519 vbi_line_width = 2000; /* might need adjustment */ 3520 3521 if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc, 3522 &dstBox, &xa, &xb, &ya, &yb, 3523 clipBoxes, width, height)) 3524 return Success; 3525 3526 if (!crtc) { 3527 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 3528 unsigned char *RADEONMMIO = info->MMIO; 3529 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3530 pPriv->videoStatus &= ~CLIENT_VIDEO_ON; 3531 } 3532 return Success; 3533 } 3534 3535 dstBox.x1 -= crtc->x; 3536 dstBox.x2 -= crtc->x; 3537 dstBox.y1 -= crtc->y; 3538 dstBox.y2 -= crtc->y; 3539 3540 bpp = pScrn->bitsPerPixel >> 3; 3541 pitch = bpp * pScrn->displayWidth; 3542 3543 switch(pPriv->overlay_deinterlacing_method){ 3544 case METHOD_BOB: 3545 case METHOD_SINGLE: 3546 mult=2; 3547 break; 3548 case METHOD_WEAVE: 3549 case METHOD_ADAPTIVE: 3550 mult=4; 3551 break; 3552 default: 3553 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n"); 3554 mult=4; 3555 } 3556 3557 id = FOURCC_YUY2; 3558 3559 top = ya>>16; 3560#if 0 3561 /* setting the ID above makes this useful - needs revisiting */ 3562 switch(id) { 3563 case FOURCC_YV12: 3564 case FOURCC_I420: 3565 top &= ~1; 3566 dstPitch = RADEON_ALIGN(width << 1, 16); 3567 srcPitch = RADEON_ALIGN(width, 4); 3568 s2offset = srcPitch * height; 3569 srcPitch2 = RADEON_ALIGN(width >> 1, 4); 3570 s3offset = (srcPitch2 * (height >> 1)) + s2offset; 3571 break; 3572 case FOURCC_UYVY: 3573 case FOURCC_YUY2: 3574 default: 3575 dstPitch = RADEON_ALIGN(width<<1, 16); 3576 srcPitch = (width<<1); 3577 break; 3578 } 3579#else 3580 dstPitch = RADEON_ALIGN(width << 1, 16); 3581 srcPitch = (width<<1); 3582#endif 3583 3584 new_size = dstPitch * height; 3585 new_size = new_size + 0x1f; /* for aligning */ 3586 alloc_size = new_size * mult; 3587 if (pPriv->capture_vbi_data) 3588 alloc_size += 2 * 2 * vbi_line_width * 21; 3589 3590 pPriv->video_offset = radeon_legacy_allocate_memory(pScrn, &pPriv->video_memory, 3591 (pPriv->doubleBuffer ? 3592 (new_size * 2) : new_size), 64, 3593 RADEON_GEM_DOMAIN_GTT); 3594 if (pPriv->video_offset == 0) 3595 return BadAlloc; 3596 3597/* I have suspicion that capture engine must be active _before_ Rage Theatre 3598 is being manipulated with.. */ 3599 3600 RADEONWaitForIdleMMIO(pScrn); 3601 display_base=INREG(RADEON_DISPLAY_BASE_ADDR); 3602 3603/* RADEONWaitForFifo(pScrn, 15); */ 3604 3605 switch(pPriv->overlay_deinterlacing_method){ 3606 case METHOD_BOB: 3607 case METHOD_SINGLE: 3608 offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10); 3609 offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10); 3610 offset3 = offset1; 3611 offset4 = offset2; 3612 break; 3613 case METHOD_WEAVE: 3614 offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10); 3615 offset2 = offset1+dstPitch; 3616 offset3 = RADEON_ALIGN(pPriv->video_offset + 2 * new_size, 0x10); 3617 offset4 = offset3+dstPitch; 3618 break; 3619 default: 3620 offset1 = RADEON_ALIGN(pPriv->video_offset, 0x10); 3621 offset2 = RADEON_ALIGN(pPriv->video_offset + new_size, 0x10); 3622 offset3 = offset1; 3623 offset4 = offset2; 3624 } 3625 3626 OUTREG(RADEON_CAP0_BUF0_OFFSET, offset1+display_base); 3627 OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET, offset2+display_base); 3628 OUTREG(RADEON_CAP0_BUF1_OFFSET, offset3+display_base); 3629 OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET, offset4+display_base); 3630 3631 OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base); 3632 3633 if(pPriv->capture_vbi_data){ 3634 if ((pPriv->encoding==2)||(pPriv->encoding==8)) { 3635 /* PAL, SECAM */ 3636 vbi_start = 5; 3637 vbi_end = 21; 3638 } else { 3639 /* NTSC */ 3640 vbi_start = 8; 3641 vbi_end = 20; 3642 } 3643 3644 vbi_offset0 = RADEON_ALIGN(pPriv->video_offset + mult * new_size * bpp, 0x10); 3645 vbi_offset1 = vbi_offset0 + dstPitch*20; 3646 OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base); 3647 OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base); 3648 OUTREG(RADEON_CAP0_VBI2_OFFSET, 0); 3649 OUTREG(RADEON_CAP0_VBI3_OFFSET, 0); 3650 OUTREG(RADEON_CAP0_VBI_V_WINDOW, vbi_start | (vbi_end<<16)); 3651 OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16); 3652 } 3653 3654 OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2); 3655 OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16); 3656 OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1)); 3657 if(mult==2){ 3658 OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB); 3659 } else { 3660 OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE); 3661 } 3662 OUTREG(RADEON_CAP0_DEBUG, 0); 3663 3664 OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01); 3665 OUTREG(RADEON_TEST_DEBUG_CNTL, 0); 3666 3667 if(! pPriv->video_stream_active) 3668 { 3669 3670 RADEONWaitForIdleMMIO(pScrn); 3671 OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 ); 3672 OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0); 3673 OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK); 3674 OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11); 3675 if(pPriv->theatre != NULL) 3676 { 3677 RADEON_RT_SetEncoding(pScrn, pPriv); 3678 } 3679 if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv); 3680 if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv); 3681 if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv); 3682 if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv); 3683 } 3684 3685 3686 /* update cliplist */ 3687 if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 3688 REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 3689 /* draw these */ 3690 if(pPriv->autopaint_colorkey) 3691 RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 3692 } 3693 3694 RADEONDisplayVideo(pScrn, crtc, pPriv, id, pPriv->video_offset, 3695 offset1+top*srcPitch, offset2+top*srcPitch, 3696 offset3+top*srcPitch, offset4+top*srcPitch, 3697 offset1+top*srcPitch, offset2+top*srcPitch, width, height, 3698 dstPitch*mult/2, xa, xb, ya, &dstBox, src_w, src_h*mult/2, 3699 drw_w, drw_h, pPriv->overlay_deinterlacing_method); 3700 3701 RADEONWaitForFifo(pScrn, 1); 3702 OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK); 3703 RADEONWaitForIdleMMIO(pScrn); 3704 while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK)); 3705 3706 3707 switch(pPriv->overlay_deinterlacing_method){ 3708 case METHOD_BOB: 3709 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 3710 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/ 3711 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3712 break; 3713 case METHOD_SINGLE: 3714 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28)); 3715 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3716 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3717 break; 3718 case METHOD_WEAVE: 3719 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28)); 3720 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0 |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3721 | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 3722 /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */ 3723 /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */ 3724 |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE); 3725 break; 3726 default: 3727 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 3728 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3729 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3730 } 3731 3732 3733 RADEONWaitForIdleMMIO(pScrn); 3734 OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE )); 3735 OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE )); 3736 3737 OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0); 3738 3739#if 0 3740 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL)); 3741/* OUTREG(RADEON_OV0_FLAG_CNTL, 8); */ 3742 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL)); 3743 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS)); 3744 3745/* OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */ 3746#endif 3747 3748 pPriv->videoStatus = CLIENT_VIDEO_ON; 3749 pPriv->video_stream_active = TRUE; 3750 3751 info->VideoTimerCallback = RADEONVideoTimerCallback; 3752 3753 return Success; 3754} 3755 /* miscellaneous TV-in helper functions */ 3756 3757static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv) 3758{ 3759 /* Adjust PAL/SECAM constants for FI1216MF tuner */ 3760 if((((pPriv->tuner_type & 0xf)==5) || 3761 ((pPriv->tuner_type & 0xf)==11)|| 3762 ((pPriv->tuner_type & 0xf)==14)) 3763 && (pPriv->fi1236!=NULL)) 3764 { 3765 if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/ 3766 { 3767 pPriv->fi1236->parm.band_low = 0xA1; 3768 pPriv->fi1236->parm.band_mid = 0x91; 3769 pPriv->fi1236->parm.band_high = 0x31; 3770 } 3771 if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/ 3772 { 3773 pPriv->fi1236->parm.band_low = 0xA3; 3774 pPriv->fi1236->parm.band_mid = 0x93; 3775 pPriv->fi1236->parm.band_high = 0x33; 3776 } 3777 } 3778 3779} 3780 3781static void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 3782{ 3783int width, height; 3784RADEONWaitForIdleMMIO(pScrn); 3785 3786/* Disable VBI capture for anything but TV tuner */ 3787switch(pPriv->encoding){ 3788 case 2: 3789 case 5: 3790 case 8: 3791 pPriv->capture_vbi_data=1; 3792 break; 3793 default: 3794 pPriv->capture_vbi_data=0; 3795 } 3796 3797switch(pPriv->encoding){ 3798 case 1: 3799 xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0); 3800 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3801 pPriv->v=25; 3802 break; 3803 case 2: 3804 xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0); 3805 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3806 pPriv->v=25; 3807 break; 3808 case 3: 3809 xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0); 3810 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3811 pPriv->v=25; 3812 break; 3813 case 4: 3814 xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE,0); 3815 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3816 pPriv->v=23; 3817 break; 3818 case 5: 3819 xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0); 3820 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3821 pPriv->v=23; 3822 break; 3823 case 6: 3824 xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0); 3825 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3826 pPriv->v=23; 3827 break; 3828 case 7: 3829 xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE, 0); 3830 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3831 pPriv->v=25; 3832 break; 3833 case 8: 3834 xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0); 3835 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3836 pPriv->v=25; 3837 break; 3838 case 9: 3839 xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0); 3840 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3841 pPriv->v=25; 3842 break; 3843 case 10: 3844 xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0); 3845 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3846 pPriv->v=25; 3847 break; 3848 case 11: 3849 xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0); 3850 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3851 pPriv->v=25; 3852 break; 3853 case 12: 3854 xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0); 3855 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3856 pPriv->v=25; 3857 break; 3858 default: 3859 pPriv->v=0; 3860 return; 3861 } 3862xf86_RT_SetInterlace(pPriv->theatre, 1); 3863width = InputVideoEncodings[pPriv->encoding].width; 3864height = InputVideoEncodings[pPriv->encoding].height; 3865xf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data); 3866} 3867 3868static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv) 3869{ 3870xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 3871switch(pPriv->encoding){ 3872 case 1: 3873 pPriv->msp3430->standard = MSP3430_PAL; 3874 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3875 break; 3876 case 2: 3877 pPriv->msp3430->standard = MSP3430_PAL; 3878 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3879 break; 3880 case 3: 3881 pPriv->msp3430->standard = MSP3430_PAL; 3882 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3883 break; 3884 case 4: 3885 pPriv->msp3430->standard = MSP3430_NTSC; 3886 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3887 break; 3888 case 5: 3889 pPriv->msp3430->standard = MSP3430_NTSC; 3890 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3891 break; 3892 case 6: 3893 pPriv->msp3430->standard = MSP3430_NTSC; 3894 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3895 break; 3896 case 7: 3897 pPriv->msp3430->standard = MSP3430_SECAM; 3898 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3899 break; 3900 case 8: 3901 pPriv->msp3430->standard = MSP3430_SECAM; 3902 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3903 break; 3904 case 9: 3905 pPriv->msp3430->standard = MSP3430_SECAM; 3906 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3907 break; 3908 case 10: 3909 pPriv->msp3430->standard = MSP3430_SECAM; 3910 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3911 break; 3912 case 11: 3913 pPriv->msp3430->standard = MSP3430_SECAM; 3914 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3915 break; 3916 case 12: 3917 pPriv->msp3430->standard = MSP3430_SECAM; 3918 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3919 break; 3920 default: 3921 return; 3922 } 3923xf86_InitMSP3430(pPriv->msp3430); 3924xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume)); 3925} 3926 3927static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv) 3928{ 3929TDA9885Ptr t=pPriv->tda9885; 3930 3931switch(pPriv->encoding){ 3932 /* PAL */ 3933 case 1: 3934 case 2: 3935 case 3: 3936 t->standard_video_if=2; 3937 t->standard_sound_carrier=1; 3938 t->modulation=2; /* negative FM */ 3939 break; 3940 /* NTSC */ 3941 case 4: 3942 case 5: 3943 case 6: 3944 t->standard_video_if=1; 3945 t->standard_sound_carrier=0; 3946 t->modulation=2; /* negative FM */ 3947 break; 3948 /* SECAM */ 3949 case 7: 3950 case 8: 3951 case 9: 3952 case 10: 3953 case 11: 3954 case 12: 3955 t->standard_video_if=0; 3956 t->standard_sound_carrier=3; 3957 t->modulation=0; /* positive AM */ 3958 break; 3959 default: 3960 return; 3961 } 3962xf86_tda9885_setparameters(pPriv->tda9885); 3963xf86_tda9885_getstatus(pPriv->tda9885); 3964xf86_tda9885_dumpstatus(pPriv->tda9885); 3965} 3966 3967static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv) 3968{ 3969/* at the moment this only affect MT2032 */ 3970switch(pPriv->encoding){ 3971 /* PAL */ 3972 case 1: 3973 case 2: 3974 case 3: 3975 pPriv->fi1236->video_if=38.900; 3976 break; 3977 /* NTSC */ 3978 case 4: 3979 case 5: 3980 case 6: 3981 pPriv->fi1236->video_if=45.7812; 3982 pPriv->fi1236->video_if=45.750; 3983 pPriv->fi1236->video_if=45.125; 3984 break; 3985 /* SECAM */ 3986 case 7: 3987 case 8: 3988 case 9: 3989 case 10: 3990 case 11: 3991 case 12: 3992 pPriv->fi1236->video_if=58.7812; 3993 break; 3994 default: 3995 return; 3996 } 3997} 3998 3999